예제 #1
0
            /// <summary>
            /// Lex a hex literal optionally followed by an integer suffix. Asserts the current
            /// character is a hex digit.
            /// </summary>
            private Token LexHexInt()
            {
                Contracts.Assert(LexCharUtils.IsHexDigit(ChCur));

                ulong u         = 0;
                bool  fOverflow = false;

                do
                {
                    if ((u & 0xF000000000000000) != 0 && !fOverflow)
                    {
                        ReportError(ErrId.IntOverflow);
                        fOverflow = true;
                    }
                    u = (u << 4) + (ulong)LexCharUtils.GetHexVal(ChCur);
                } while (LexCharUtils.IsHexDigit(ChNext()));

                if (fOverflow)
                {
                    u = ulong.MaxValue;
                }

                return(new IntLitToken(GetSpan(), u, LexIntSuffix() | IntLitKind.Hex));
            }
예제 #2
0
            /// <summary>
            /// Lex a character escape. Returns true if successful (ch is valid).
            /// </summary>
            private bool FLexEscChar(bool fUniOnly, out uint u)
            {
                Contracts.Assert(ChCur == '\\');

                int  ichErr = _cursor.IchCur;
                bool fUni;
                int  cchHex;

                switch (ChNext())
                {
                case 'u':
                    fUni   = true;
                    cchHex = 4;
                    goto LHex;

                case 'U':
                    fUni   = true;
                    cchHex = 8;
                    goto LHex;

                default:
                    if (!fUniOnly)
                    {
                        switch (ChCur)
                        {
                        default:
                            goto LBad;

                        case 'x':
                        case 'X':
                            fUni   = false;
                            cchHex = 4;
                            goto LHex;

                        case '\'':
                            u = 0x0027;
                            break;

                        case '"':
                            u = 0x0022;
                            break;

                        case '\\':
                            u = 0x005C;
                            break;

                        case '0':
                            u = 0x0000;
                            break;

                        case 'a':
                            u = 0x0007;
                            break;

                        case 'b':
                            u = 0x0008;
                            break;

                        case 'f':
                            u = 0x000C;
                            break;

                        case 'n':
                            u = 0x000A;
                            break;

                        case 'r':
                            u = 0x000D;
                            break;

                        case 't':
                            u = 0x0009;
                            break;

                        case 'v':
                            u = 0x000B;
                            break;
                        }
                        ChNext();
                        return(true);
                    }
LBad:
                    ReportError(ichErr, _cursor.IchCur, ErrId.BadEscape);
                    u = 0;
                    return(false);
                }

LHex:
                bool fRet = true;

                ChNext();

                u = 0;
                for (int ich = 0; ich < cchHex; ich++)
                {
                    if (!LexCharUtils.IsHexDigit(ChCur))
                    {
                        fRet = (ich > 0);
                        if (fUni || !fRet)
                        {
                            ReportError(ichErr, _cursor.IchCur, ErrId.BadEscape);
                        }
                        break;
                    }
                    u = (u << 4) + (uint)LexCharUtils.GetHexVal(ChCur);
                    ChNext();
                }
                return(fRet);
            }
예제 #3
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()));
            }