Beispiel #1
0
          /// <summary>
          /// Reads a quoted name with any character in it, until a '"' or '>' is found
          /// </summary>
          internal static Name    ReadQuotedName(char c, TextStream S)
          {
              List <string> results = new List <string>();

              string result = "";

              // Read until we reach the closing '"'
              if (!S.EOT)
              {
                  c = S.Pop();
                  while (c != CHAR_STRING_DELIMITER)
                  {
                      if (c == CHAR_CHILD_MARKER)
                      {
                          // Add a new string
                          results.Add(result);
                          result = "";
                      }
                      else
                      {
                          result += c;
                      }
                      if (S.EOT)
                      {
                          break;
                      }
                      c = S.Pop();
                  }
              }

              results.Add(result);

              return(new Name(results.ToArray()));
          }
Beispiel #2
0
          /// <summary>
          /// Reads a name while alphanumeric characters are found
          /// </summary>
          internal static Name    Read(char c, TextStream S)
          {
              List <string> results = new List <string>();

              string result = "";

              while ((c == CHAR_CHILD_MARKER || c == CHAR_STRING_DELIMITER || c == CHAR_SPECIAL_STRING_DELIMITER_START || c == CHAR_SPECIAL_STRING_DELIMITER_END || IsAlphaNumeric(c)))
              {
                  if (c == CHAR_STRING_DELIMITER)
                  {
                      // Read a quoted-name like "\"example\""
                      Name temp = ReadQuotedName(c, S);
                      for (int i = 0; i < temp.m_name.Length - 1; i++)
                      {
                          results.Add(temp.m_name[i]);
                      }
                      result = temp.m_name[temp.m_name.Length - 1];
                  }
                  else if (c == CHAR_SPECIAL_STRING_DELIMITER_START)
                  {
                      // Read a special-name like "<example>"
                      result = "" + c;
                      while ((c = S.Pop()) != CHAR_SPECIAL_STRING_DELIMITER_END)
                      {
                          result += c;
                      }
                      result += c;
                  }
                  else if (c == CHAR_CHILD_MARKER)
                  {
                      // Add a new string
                      results.Add(result);
                      result = "";
                  }
                  else
                  {
                      result += c;
                  }

                  if (S.EOT)
                  {
                      break;
                  }
                  c = S.Pop();
              }
              results.Add(result);
              S.GoBackOne();

              return(new Name(results.ToArray()));
          }
Beispiel #3
0
          /// <summary>
          /// Builds a name
          /// </summary>
          /// <param name="c"></param>
          /// <param name="S"></param>
          /// <returns></returns>
          public static Name      Read(string _fullyQualifiedName)
          {
              if (_fullyQualifiedName == null || _fullyQualifiedName == "")
              {
                  return(null);
              }

              TextStream S = new TextStream(_fullyQualifiedName);

              return(Read(S.Pop(), S));
          }
Beispiel #4
0
          public static string    Read(TextStream S)
          {
              string result = "";

              char c = S.Pop();

              if (c == CHAR_COMMENT)
              {
                  c = S.Pop();
              }

              // Read until we reach EOL
              while (c != '\n')
              {
                  if (c != '\r')
                  {
                      result += c;
                  }
                  c = S.Pop();
              }

              return(result);
          }
Beispiel #5
0
      public Parser(string _text)
      {
          m_stream = new TextStream(_text + "\n");

          Push(STATE.COLLECTION);
          m_root = PushCollection(null);

          Name name = null;
          char c;                               // Last read character in the stream

          while (!m_stream.EOT)
          {
              c = m_stream.Pop();                       // Get current character

              if (IsSpaceNoEOL(c))
              {
                  continue;                             // Skip space
              }
              if (c == CHAR_COMMENT)
              {
                  // Read till the end of line
                  CommentParser.Read(m_stream);
                  if (m_state.Peek() == STATE.NAME)
                  {
                      // In NAME state, a new line acts as a collection item separator
                      Pop();
                  }
                  continue;
              }

              if (c == CHAR_PREPROCESSOR)
              {
                  // Read till the end of line and keep for further parsing...
                  Token T = AddToken(Token.TYPE.PREPROCESSOR_DIRECTIVE, null);
                  T.m_value = CommentParser.Read(m_stream);
                  continue;
              }


              switch (m_state.Peek())
              {
              //////////////////////////////////////////////////////////////////////////
              // In NAME state, we expect:
              //	• an alias assignment
              //	• a child assignment
              //	• a feature assignment
              //	• a constructor
              //	• a collection end
              //
              case STATE.NAME:
                  if (c == CHAR_COLLECTION_ITEM_SEPARATOR || c == '\n')
                  {
                      // A new line acts as a collection item separator, go back to previous state
                      Pop();
                      continue;
                  }
                  else if (c == CHAR_ALIAS_ASSIGNMENT || c == '⇒')
                  {
                      // Check if it's an assignment or a parent-child definition
                      if (c == '⇒' || m_stream.Peek == CHAR_HIERARCHY)
                      {
                          // Parent-Child hierarchy marker
                          if (c != '⇒')
                          {
                              c = m_stream.Pop();                                               // Consume character
                          }
                          AddToken(Token.TYPE.HIERARCHY_MARKER, null);
                          Pop();
                          Push(STATE.CHILD);
                          continue;
                      }

                      // Last parsed name was in fact an alias
                      MakeLastTokenA(Token.TYPE.ALIAS);
                      Pop();
                      Push(STATE.ALIAS);
                      continue;
                  }
                  else if (c == CHAR_FEATURES_COLLECTION_MARKER)
                  {
                      // Parent-Child features marker
                      AddToken(Token.TYPE.FEATURE_MARKER, null);
                      Pop();
                      Push(STATE.CHILD);
                      continue;
                  }
                  else if (c == CHAR_CONSTRUCTOR_START)
                  {
                      // Entering constructor definition
                      Token T = AddToken(Token.TYPE.CONSTRUCTOR, null);
                      T.m_value = PushCollection(T);
                      Pop();
                      Push(STATE.CONSTRUCTOR);
                      continue;
                  }
                  else if (c == CHAR_COLLECTION_END)
                  {
                      // Exiting collection
                      Pop();                                    // Pop name
                      Pop();                                    // Pop collection
                      PopCollection();
                      Push(STATE.NAME);                         // Assume an entire collection is a single name token
                      continue;
                  }

                  SyntaxError(m_stream, c, "a name");

                  break;

              //////////////////////////////////////////////////////////////////////////
              // In VALUE state, we expect:
              //	• A value separator
              //	• The end of the constructor
              //
              case STATE.VALUE:
                  if (c == CHAR_COLLECTION_ITEM_SEPARATOR || c == '\n')
                  {
                      // A new line acts as a separator, go back to previous state
                      Pop();
                      continue;
                  }
                  else if (c == CHAR_CONSTRUCTOR_END)
                  {
                      // Exit the constructor
                      Pop();                                    // Pop value
                      Pop();                                    // Pop constructor
                      PopCollection();
                      Push(STATE.NAME);                         // Assume a constructed name is a single name token
                      continue;
                  }

                  SyntaxError(m_stream, c, "a constructor value");

                  break;

              //////////////////////////////////////////////////////////////////////////
              // In collection state, we expect:
              //	• a name
              //	• a collection start
              //	• a collection end
              //	• a separator
              //
              case STATE.COLLECTION:
                  if (c == CHAR_COLLECTION_ITEM_SEPARATOR || c == '\n')
                  {
                      continue;
                  }
                  if (c == CHAR_COLLECTION_START)
                  {
                      // Start a new collection
                      Token T = AddToken(Token.TYPE.COLLECTION, null);
                      T.m_value = PushCollection(T);
                      Push(STATE.COLLECTION);
                      continue;
                  }
                  else if (c == CHAR_COLLECTION_END)
                  {
                      // Exit the collection
                      Pop();                                    // Pop collection
                      PopCollection();
                      Push(STATE.NAME);                         // Assume an entire collection is a single name token
                      continue;
                  }
                  else if (ReadName(c, m_stream, ref name))
                  {
                      // We just read a name
                      AddToken(Token.TYPE.NAME, name);
                      Push(STATE.NAME);
                      continue;
                  }

                  SyntaxError(m_stream, c, "collection");

                  break;

              //////////////////////////////////////////////////////////////////////////
              // In CONSTRUCTOR state, we expect:
              //	• A value
              //	• An alias name
              //	• The end of the constructor
              //
              case STATE.CONSTRUCTOR:
                  if (c == '\n')
                  {
                      continue;
                  }

                  if (c == CHAR_CONSTRUCTOR_END)
                  {
                      // Exit the constructor
                      Pop();                                    // Pop constructor
                      PopCollection();
                      Push(STATE.NAME);                         // Assume a constructed name is a single name token
                      continue;
                  }
                  else if (ReadName(c, m_stream, ref name))
                  {
                      // We just read a name and it MUST be an alias!
                      AddToken(Token.TYPE.NAME, name);
                      Push(STATE.NAME);
                      continue;
                  }

                  SyntaxError(m_stream, c, "a constructor");

                  break;

              //////////////////////////////////////////////////////////////////////////
              // In CHILD state, we expect:
              //	• a new NAME
              //	• a new collection
              //
              case STATE.CHILD:
                  if (c == '\n')
                  {
                      continue;
                  }

                  if (c == CHAR_COLLECTION_START)
                  {
                      // Start a new collection
                      Pop();

                      Token T = AddToken(Token.TYPE.COLLECTION, null);
                      T.m_value = PushCollection(T);
                      Push(STATE.COLLECTION);
                      continue;
                  }
                  else if (ReadName(c, m_stream, ref name))
                  {
                      // We just read a name
                      Pop();

                      AddToken(Token.TYPE.NAME, name);
                      Push(STATE.NAME);
                      continue;
                  }

                  SyntaxError(m_stream, c, "child");

                  break;

              //////////////////////////////////////////////////////////////////////////
              // In ALIAS state, we expect:
              //	• a new NAME
              //
              case STATE.ALIAS:
                  if (c == '\n')
                  {
                      continue;
                  }

                  if (ReadName(c, m_stream, ref name))
                  {
                      // We just read a name
                      Pop();
                      AddToken(Token.TYPE.NAME, name);
                      Push(STATE.NAME);
                      continue;
                  }

                  SyntaxError(m_stream, c, "an alias");

                  break;
              }
          }

          // Verify we're back to the root collection
          if (m_state.Count != 1)
          {
              throw new Exception("Leaving parsing with " + (m_state.Count - 1) + " states remaining, not at root level!");
          }
          if (m_state.Peek() != STATE.COLLECTION)
          {
              throw new Exception("Leaving parsing with a single state that is not the root COLLECTION!");
          }
      }