Exemple #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        /// <remarks>
        ///
        /// See https://www.dmtf.org/sites/default/files/standards/documents/DSP0221_3.0.1.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.
        ///
        ///     Integer 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 */
        ///     Integer /* 16-bit integer property */ MyProperty; /* and a multi-line
        ///                             comment */
        ///
        /// </remarks>
        public static (CommentToken, Lexer) ReadCommentToken(SourceReader reader)
        {
            var thisReader  = reader;
            var sourceChar  = default(SourceChar);
            var sourceChars = new List <SourceChar>();

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

            case '*':     // multi-line
                (sourceChar, thisReader) = thisReader.Read('*');
                sourceChars.Add(sourceChar);
                // read the comment text
                while (!thisReader.Eof())
                {
                    (sourceChar, thisReader) = thisReader.Read();
                    sourceChars.Add(sourceChar);
                    if ((sourceChar.Value == '*') && thisReader.Peek('/'))
                    {
                        // read the closing sequence
                        (sourceChar, thisReader) = thisReader.Read('/');
                        sourceChars.Add(sourceChar);
                        break;
                    }
                }
                break;

            default:
                throw new UnexpectedCharacterException(reader.Peek());
            }
            // return the result
            var extent = SourceExtent.From(sourceChars);

            return(new CommentToken(extent), new Lexer(thisReader));
        }
        public ScannerResult ReadToken(SourceReader reader)
        {
            var peek = reader.Peek();

            // make sure the rule for the next character is in the rule cache
            if (!this.ScannerCache.ContainsKey(peek.Value))
            {
                this.ScannerCache.Add(
                    peek.Value,
                    this.Scanners.FirstOrDefault(r => r.Match.Matches(peek.Value))
                    ?? throw new UnexpectedCharacterException(peek)
                    );
            }
            // apply the scanner for the next character
            return(this.ScannerCache[peek.Value].Action.Invoke(reader));
        }
Exemple #3
0
        public IEnumerable <Token> Scan()
        {
            while (!reader.EndOfStream)
            {
                reader.ReadWhile(Char.IsWhiteSpace);
                var startLocation = reader.Location;
                var lexeme        = String.Empty;
                var tokenKind     = TokenKind.Unknown;
                var c             = (char)reader.Peek();

                switch (c)
                {
                case '+':
                    reader.Read();
                    tokenKind = TokenKind.Plus;
                    lexeme    = "+";
                    break;

                case '-':
                    reader.Read();
                    tokenKind = TokenKind.Minus;
                    lexeme    = "-";
                    break;

                case '*':
                    reader.Read();
                    tokenKind = TokenKind.Mul;
                    lexeme    = "*";
                    break;

                case '/':
                    reader.Read();
                    tokenKind = TokenKind.Div;
                    lexeme    = "/";
                    break;

                case '(':
                    reader.Read();
                    tokenKind = TokenKind.LParen;
                    lexeme    = "(";
                    break;

                case ')':
                    reader.Read();
                    tokenKind = TokenKind.RParen;
                    lexeme    = ")";
                    break;

                case '[':
                    reader.Read();
                    tokenKind = TokenKind.LBracket;
                    lexeme    = "[";
                    break;

                case ']':
                    reader.Read();
                    tokenKind = TokenKind.RBracket;
                    lexeme    = "]";
                    break;

                case '{':
                    reader.Read();
                    tokenKind = TokenKind.LCurly;
                    lexeme    = "{";
                    break;

                case '}':
                    reader.Read();
                    tokenKind = TokenKind.RCurly;
                    lexeme    = "}";
                    break;

                case ',':
                    reader.Read();
                    tokenKind = TokenKind.Comma;
                    lexeme    = ",";
                    break;

                case '.':
                    reader.Read();
                    tokenKind = TokenKind.Period;
                    lexeme    = ".";
                    break;

                case ';':
                    reader.Read();
                    tokenKind = TokenKind.Semicolon;
                    lexeme    = ";";
                    break;

                case ':':
                    reader.Read();
                    tokenKind = TokenKind.Colon;
                    lexeme    = ":";
                    break;

                case '?':
                    reader.Read();
                    if (reader.Peek() == '?')
                    {
                        reader.Read();
                        tokenKind = TokenKind.QMark2;
                        lexeme    = "??";
                    }
                    else
                    {
                        tokenKind = TokenKind.QMark;
                        lexeme    = "?";
                    }
                    break;

                case '!':
                    reader.Read();
                    tokenKind = TokenKind.EMark;
                    lexeme    = "!";
                    break;

                default:
                    if (Char.IsDigit(c))
                    {
                        lexeme    = reader.ReadWhile(Char.IsDigit);
                        tokenKind = TokenKind.Number;
                    }
                    else if (Char.IsLetterOrDigit(c))
                    {
                        lexeme = reader.ReadWhile(Char.IsLetterOrDigit);

                        if (!keywords.TryGetValue(lexeme, out tokenKind))
                        {
                            tokenKind = TokenKind.Ident;
                        }
                    }
                    else
                    {
                        lexeme = reader.ReadWhile(x => !Char.IsWhiteSpace(x));
                    }
                    break;
                }

                yield return(new Token(tokenKind, lexeme, new TextSpan(startLocation, reader.Location)));
            }

            yield return(new Token(TokenKind.Eof, "end of file", new TextSpan(reader.Location, reader.Location)));
        }