예제 #1
0
            /// <summary>
            /// Lex a line termination character. Transforms CRLF into a single LF.
            /// Updates the line mapping. When this "drops" a character and sb is not
            /// null, it adds the character to sb. It does NOT add the returned character
            /// to the sb.
            /// </summary>
            private char LexLineTerm(StringBuilder sb = null)
            {
                Contracts.Assert(LexCharUtils.StartKind(ChCur) == LexStartKind.LineTerm);
                int ichMin = _cursor.IchCur;

                if (ChCur == '\xD' && ChPeek(1) == '\xA')
                {
                    if (sb != null)
                    {
                        sb.Append(ChCur);
                    }
                    ChNext();
                }
                char ch = ChCur;

                ChNext();

                if (_ichMinTok == ichMin)
                {
                    // Not nested.
                    _queue.Enqueue(new NewLineToken(GetSpan(), false));
                }
                else
                {
                    // Is nested.
                    _queue.Enqueue(new NewLineToken(GetTextSpan(ichMin, _cursor.IchCur), true));
                }
                _fLineStart = true;
                return(ch);
            }
예제 #2
0
 /// <summary>
 /// Skip over an error character. Always returns null.
 /// REVIEW: Should we skip over multiple?
 /// </summary>
 private Token LexError()
 {
     _sb.Length = 0;
     do
     {
         _sb.AppendFormat("{0}({1})", ChCur, LexCharUtils.GetUniEscape(ChCur));
     } while (LexCharUtils.StartKind(ChNext()) == LexStartKind.None && !Eof);
     return(new ErrorToken(GetSpan(), ErrId.BadChar, _sb.ToString()));
 }
예제 #3
0
 /// <summary>
 /// Lex a sequence of spacing characters.
 /// Always returns null.
 /// </summary>
 private Token LexSpace()
 {
     Contracts.Assert(LexCharUtils.StartKind(ChCur) == LexStartKind.Space);
     while (LexCharUtils.IsSpace(ChNext()))
     {
         ;
     }
     return(null);
 }
예제 #4
0
            private Token FetchToken()
            {
                Contracts.Assert(!Eof);
                StartTok();

                LexStartKind kind = LexCharUtils.StartKind(ChCur);

                if (kind != LexStartKind.Space && kind != LexStartKind.PreProc)
                {
                    _fLineStart = false;
                }

                switch (kind)
                {
                case LexStartKind.Punc:
                    return(LexPunc());

                case LexStartKind.NumLit:
                    return(LexNumLit());

                case LexStartKind.StrLit:
                    return(LexStrLit());

                case LexStartKind.Verbatim:
                    if (ChPeek(1) == '"')
                    {
                        return(LexStrLit());
                    }
                    if (LexCharUtils.StartKind(ChPeek(1)) == LexStartKind.Ident)
                    {
                        return(LexIdent());
                    }
                    ChNext();
                    ReportError(ErrId.VerbatimLiteralExpected);
                    return(null);

                case LexStartKind.Ident:
                    return(LexIdent());

                case LexStartKind.Comment:
                    return(LexComment());

                case LexStartKind.Space:
                    return(LexSpace());

                case LexStartKind.LineTerm:
                    LexLineTerm();
                    return(null);

                case LexStartKind.PreProc:
                    return(LexPreProc());

                default:
                    return(LexError());
                }
            }
예제 #5
0
            /// <summary>
            /// Called to lex a numeric literal or a Dot token. Asserts the current
            /// character lex type is LexCharType.NumLit.
            /// </summary>
            private Token LexNumLit()
            {
                Contracts.Assert(LexCharUtils.StartKind(ChCur) == LexStartKind.NumLit);
                Contracts.Assert(LexCharUtils.IsDigit(ChCur) || ChCur == '.');

                // A dot not followed by a digit is just a Dot. This is a very common case (hence first).
                if (ChCur == '.' && !LexCharUtils.IsDigit(ChPeek(1)))
                {
                    return(LexPunc());
                }

                // Check for a hex literal. Note that 0x followed by a non-hex-digit is really a 0 followed
                // by an identifier.
                if (ChCur == '0' && (ChPeek(1) == 'x' || ChPeek(1) == 'X') && LexCharUtils.IsHexDigit(ChPeek(2)))
                {
                    // Advance to first hex digit.
                    ChNext();
                    ChNext();
                    return(LexHexInt());
                }

                // Decimal literal (possible floating point).
                Contracts.Assert(LexCharUtils.IsDigit(ChCur) || ChCur == '.' && LexCharUtils.IsDigit(ChPeek(1)));
                bool fExp = false;
                bool fDot = ChCur == '.';

                _sb.Length = 0;
                _sb.Append(ChCur);

                for (; ;)
                {
                    if (ChNext() == '.')
                    {
                        if (fDot || !LexCharUtils.IsDigit(ChPeek(1)))
                        {
                            break;
                        }
                        fDot = true;
                    }
                    else if (!LexCharUtils.IsDigit(ChCur))
                    {
                        break;
                    }
                    _sb.Append(ChCur);
                }

                // Check for an exponent.
                if (ChCur == 'e' || ChCur == 'E')
                {
                    char chTmp = ChPeek(1);
                    if (LexCharUtils.IsDigit(chTmp) || (chTmp == '+' || chTmp == '-') && LexCharUtils.IsDigit(ChPeek(2)))
                    {
                        fExp = true;
                        _sb.Append(ChCur);
                        _sb.Append(ChNext());
                        while (LexCharUtils.IsDigit(chTmp = ChNext()))
                        {
                            _sb.Append(chTmp);
                        }
                    }
                }

                bool fReal = fDot || fExp;
                char chSuf = LexRealSuffix(fReal);

                if (fReal || chSuf != '\0')
                {
                    return(LexRealNum(chSuf));
                }

                // Integer type.
                return(LexDecInt(LexIntSuffix()));
            }