internal static AliasIdentifierToken Read(ILexerStream stream)
 {
     var extent = new SourceExtent(stream);
     var sourceChars = new List<char>();
     // read the first character
     sourceChars.Add(stream.ReadChar('$'));
     // read the name
     var nameChars = new List<char>();
     while (!stream.Eof)
     {
         extent = extent.WithEndExtent(stream);
         var peek = stream.Peek();
         if (char.IsLetterOrDigit(peek) || ("_".IndexOf(peek) != -1) )
         {
             var @char = stream.Read();
             sourceChars.Add(@char);
             nameChars.Add(@char);
         }
         else
         {
             break;
         }
     }
     // return the result
     extent = extent.WithText(sourceChars);
     var name = new string(nameChars.ToArray());
     return new AliasIdentifierToken(extent, name);
 }
 internal static StringLiteralToken Read(ILexerStream stream)
 {
     var extent = new SourceExtent(stream);
     var sourceChars = new List<char>();
     // read the first character
     sourceChars.Add(stream.ReadChar('"'));
     // read the remaining characters
     var parser = new StringParser();
     while (!stream.Eof)
     {
         var peek = stream.Peek();
         sourceChars.Add(peek);
         if ((peek == '"') && !parser.IsEscaped)
         {
             parser.ConsumeEof();
             break;
         }
         else
         {
             parser.ConsumeChar(stream.Read());
         }
     }
     // read the last character
     sourceChars.Add(stream.ReadChar('"'));
     // process any escape sequences in the string
     var unescaped = parser.OutputString.ToString();
     // return the result
     extent = extent.WithText(sourceChars);
     return new StringLiteralToken(extent, unescaped);
 }
Example #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        /// <remarks>
        ///
        /// See http://www.dmtf.org/sites/default/files/standards/documents/DSP0221_3.0.0a.pdf
        ///
        /// A.17.3 String values
        ///
        /// Unless explicitly specified via ABNF rule WS, no whitespace is allowed between the elements of the rules
        /// in this ABNF section.
        ///
        ///     stringValue   = DOUBLEQUOTE *stringChar DOUBLEQUOTE
        ///                     *( *WS DOUBLEQUOTE *stringChar DOUBLEQUOTE )
        ///     stringChar    = stringUCSchar / stringEscapeSequence
        ///
        /// </remarks>
        private static StringLiteralToken ReadStringLiteralToken(ILexerStream stream)
        {
            // BUGBUG - no support for *( *WS DOUBLEQUOTE *stringChar DOUBLEQUOTE )
            // BUGBUG - incomplete escape sequences
            // BUGBUG - no support for UCS characters
            var sourceChars = new List <SourceChar>();

            // read the first character
            sourceChars.Add(stream.ReadChar('"'));
            // read the remaining characters
            var parser = new StringLiteralParser();

            while (!stream.Eof)
            {
                var peek = stream.Peek();
                if (StringValidator.IsDoubleQuote(peek.Value) && !parser.IsEscaped)
                {
                    parser.ConsumeEos();
                    break;
                }
                else
                {
                    sourceChars.Add(peek);
                    parser.ConsumeChar(stream.Read());
                }
            }
            // read the last character
            sourceChars.Add(stream.ReadChar('"'));
            // process any escape sequences in the string
            var unescaped = parser.OutputString.ToString();
            // return the result
            var extent = new SourceExtent(sourceChars);

            return(new StringLiteralToken(extent, unescaped));
        }
Example #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        /// <remarks>
        ///
        /// See http://www.dmtf.org/sites/default/files/standards/documents/DSP0221_3.0.0.pdf
        ///
        /// A.13 Names
        ///
        /// MOF names are identifiers with the format defined by the IDENTIFIER rule.
        /// No whitespace is allowed between the elements of the rules in this ABNF section.
        ///
        ///     IDENTIFIER          = firstIdentifierChar *( nextIdentifierChar )
        ///     firstIdentifierChar = UPPERALPHA / LOWERALPHA / UNDERSCORE
        ///     nextIdentifierChar  = firstIdentifierChar / decimalDigit
        ///     elementName         = localName / schemaQualifiedName
        ///     localName           = IDENTIFIER
        ///
        /// </remarks>
        private static IdentifierToken ReadIdentifierToken(ILexerStream stream)
        {
            var sourceChars = new List <SourceChar>();
            var nameChars   = new List <char>();
            // firstIdentifierChar
            var peek = stream.Peek();

            if (!StringValidator.IsFirstIdentifierChar(peek.Value))
            {
                throw new InvalidOperationException(
                          string.Format("Unexpected character '{0}' encountered", peek.Value));
            }
            // *( nextIdentifierChar )
            while (!stream.Eof)
            {
                peek = stream.Peek();
                if (StringValidator.IsNextIdentifierChar(peek.Value))
                {
                    var @char = stream.Read();
                    sourceChars.Add(@char);
                    nameChars.Add(@char.Value);
                }
                else
                {
                    break;
                }
            }
            // return the result
            var extent = new SourceExtent(sourceChars);
            var name   = new string(nameChars.ToArray());

            return(new IdentifierToken(extent, name));
        }
Example #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        /// <remarks>
        ///
        /// See http://www.dmtf.org/sites/default/files/standards/documents/DSP0221_3.0.0a.pdf
        ///
        /// A.17.1 Integer value
        ///
        /// No whitespace is allowed between the elements of the rules in this ABNF section.
        ///
        ///     integerValue         = binaryValue / octalValue / hexValue / decimalValue
        ///
        ///     binaryValue          = [ "+" / "-" ] 1*binaryDigit ( "b" / "B" )
        ///     binaryDigit          = "0" / "1"
        ///
        ///     octalValue           = [ "+" / "-" ] unsignedOctalValue
        ///     unsignedOctalValue   = "0" 1*octalDigit
        ///     octalDigit           = "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7"
        ///
        ///     hexValue             = [ "+" / "-" ] ( "0x" / "0X" ) 1*hexDigit
        ///     hexDigit             = decimalDigit / "a" / "A" / "b" / "B" / "c" / "C" /
        ///                                           "d" / "D" / "e" / "E" / "f" / "F"
        ///
        ///     decimalValue         = [ "+" / "-" ] unsignedDecimalValue
        ///     unsignedDecimalValue = positiveDecimalDigit *decimalDigit
        ///     decimalDigit         = "0" / positiveDecimalDigit
        ///     positiveDecimalDigit = "1"..."9"
        ///
        /// </remarks>
        private static NumericLiteralToken ReadNumericLiteralToken(ILexerStream stream)
        {
            var sourceChars = new List <SourceChar>();
            // read the sign (if there is one)
            var sign = 0;
            var peek = stream.Peek();

            switch (peek.Value)
            {
            case '+':
                sign = 1;
                sourceChars.Add(stream.Read());
                break;

            case '-':
                sign = -1;
                sourceChars.Add(stream.Read());
                break;
            }
            // read the remaining characters
            sourceChars.Add(stream.ReadDigit());
            while (!stream.Eof && stream.PeekDigit())
            {
                sourceChars.Add(stream.ReadDigit());
            }
            // return the result
            var extent = new SourceExtent(sourceChars);

            long    longValue;
            decimal decimalValue;

            if (long.TryParse(extent.Text, out longValue))
            {
                return(new IntegerLiteralToken(extent, longValue));
            }
            if (decimal.TryParse(extent.Text, out decimalValue))
            {
                return(new RealLiteralToken(extent, decimalValue));
            }

            throw new NotSupportedException($"{extent.Text} is not a valid number");
        }
Example #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        /// <remarks>
        ///
        /// See http://www.dmtf.org/sites/default/files/standards/documents/DSP0221_3.0.0.pdf
        ///
        /// 5.4 Comments
        /// Comments in a MOF file do not create, modify, or annotate language elements. They shall be treated as if
        /// they were whitespace.
        ///
        /// Comments may appear anywhere in MOF syntax where whitespace is allowed and are indicated by either
        /// a leading double slash( // ) or a pair of matching /* and */ character sequences. Occurrences of these
        /// character sequences in string literals shall not be treated as comments.
        ///
        /// A // comment is terminated by the end of line (see 5.3), as shown in the example below.
        ///
        ///     uint16 MyProperty; // This is an example of a single-line comment
        ///
        /// A comment that begins with /* is terminated by the next */ sequence, or by the end of the MOF file,
        /// whichever comes first.
        ///
        ///     /* example of a comment between property definition tokens and a multi-line comment */
        ///     uint16 /* 16-bit integer property */ MyProperty; /* and a multi-line
        ///                             comment */
        ///
        /// </remarks>
        private static CommentToken ReadCommentToken(ILexerStream stream)
        {
            var sourceChars = new List <SourceChar>();

            sourceChars.Add(stream.ReadChar('/'));
            switch (stream.Peek().Value)
            {
            case '/':     // single-line
                sourceChars.Add(stream.ReadChar('/'));
                // read the comment text
                while (!stream.Eof && !StringValidator.IsLineTerminator(stream.Peek().Value))
                {
                    sourceChars.Add(stream.Read());
                }
                ;
                break;

            case '*':     // multi-line
                sourceChars.Add(stream.ReadChar('*'));
                // read the comment text
                while (!stream.Eof)
                {
                    var @char = stream.Read();
                    sourceChars.Add(@char);
                    if ((@char.Value == '*') && stream.PeekChar('/'))
                    {
                        // read the closing sequence
                        sourceChars.Add(stream.ReadChar('/'));
                        break;
                    }
                }
                break;

            default:
                throw new InvalidOperationException(
                          string.Format("Unexpected character '{0}'.", stream.Peek()));
            }
            // return the result
            var extent = new SourceExtent(sourceChars);

            return(new CommentToken(extent));
        }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="stream"></param>
 /// <returns></returns>
 /// <remarks>
 /// 
 /// See http://www.dmtf.org/sites/default/files/standards/documents/DSP0221_3.0.0a.pdf
 /// 5.2 - Whitespace
 /// 
 /// Whitespace in a MOF file is any combination of the following characters:
 /// 
 ///     Space (U+0020),
 ///     Horizontal Tab (U+0009),
 ///     Carriage Return (U+000D) and
 ///     Line Feed (U+000A).
 /// 
 /// </remarks>
 internal static WhitespaceToken Read(ILexerStream stream)
 {
     var extent = new SourceExtent(stream);
     var sourceChars = new List<char>();
     // read the first whitespace character
     sourceChars.Add(stream.ReadWhitespace());
     // read the remaining whitespace
     while (!stream.Eof && char.IsWhiteSpace(stream.Peek()))
     {
         sourceChars.Add(stream.Read());
     }
     // return the result
     extent = extent.WithText(sourceChars);
     return new WhitespaceToken(extent);
 }
Example #8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        /// <remarks>
        ///
        /// See http://www.dmtf.org/sites/default/files/standards/documents/DSP0221_3.0.0a.pdf
        ///
        /// 5.2 - Whitespace
        ///
        /// Whitespace in a MOF file is any combination of the following characters:
        ///
        ///     Space (U+0020),
        ///     Horizontal Tab (U+0009),
        ///     Carriage Return (U+000D) and
        ///     Line Feed (U+000A).
        ///
        /// The WS ABNF rule represents any one of these whitespace characters:
        ///
        ///     WS = U+0020 / U+0009 / U+000D / U+000A
        ///
        /// </remarks>
        private static WhitespaceToken ReadWhitespaceToken(ILexerStream stream)
        {
            var sourceChars = new List <SourceChar>();

            // read the first whitespace character
            sourceChars.Add(stream.ReadWhitespace());
            // read the remaining whitespace
            while (!stream.Eof && StringValidator.IsWhitespace(stream.Peek().Value))
            {
                sourceChars.Add(stream.Read());
            }
            // return the result
            var extent = new SourceExtent(sourceChars);

            return(new WhitespaceToken(extent));
        }
        internal static MultilineCommentToken Read(ILexerStream stream)
        {
            var extent = new SourceExtent(stream);
            var sourceChars = new List<char>();
            // read the opening sequence
            sourceChars.Add(stream.ReadChar('/'));
            sourceChars.Add(stream.ReadChar('*'));
            // read the comment text
            while (!stream.Eof)
            {
                var c = stream.Read();
                sourceChars.Add(c);

                if (c == '*' && stream.PeekChar('/'))
                    break;
            }
            // read the closing  sequence
            sourceChars.Add(stream.ReadChar('/'));
            // return the result
            extent = extent.WithText(sourceChars);
            return new MultilineCommentToken(extent);
        }