예제 #1
0
            /// <summary>
            /// Lex a comment.
            /// </summary>
            private Token LexComment()
            {
                Contracts.Assert(ChCur == '/');
                int ichErr = _cursor.IchCur;

                switch (ChPeek(1))
                {
                default:
                    return(LexPunc());

                case '/':
                    // Single line comment.
                    ChNext();
                    _sb.Length = 0;
                    _sb.Append("//");
                    for (; ;)
                    {
                        if (LexCharUtils.IsLineTerm(ChNext()) || Eof)
                        {
                            return(new CommentToken(GetSpan(), _sb.ToString(), 0));
                        }
                        _sb.Append(ChCur);
                    }

                case '*':
                    /* block comment */
                    ChNext();
                    _sb.Length = 0;
                    _sb.Append("/*");
                    ChNext();
                    int lines = 0;
                    for (; ;)
                    {
                        if (Eof)
                        {
                            ReportError(ichErr, _cursor.IchCur, ErrId.UnterminatedComment);
                            break;
                        }
                        char ch = ChCur;
                        if (LexCharUtils.IsLineTerm(ch))
                        {
                            ch = LexLineTerm(_sb);
                            lines++;
                        }
                        else
                        {
                            ChNext();
                        }
                        _sb.Append(ch);
                        if (ch == '*' && ChCur == '/')
                        {
                            _sb.Append('/');
                            ChNext();
                            break;
                        }
                    }
                    // We support comment keywords.
                    KeyWordTable.KeyWordKind kind;
                    NormStr nstr = _lex._pool.Add(_sb);
                    if (_lex._kwt.IsKeyWord(nstr, out kind))
                    {
                        return(KeyToken.CreateKeyWord(GetSpan(), nstr.ToString(), kind.Kind, kind.IsContextKeyWord));
                    }
                    return(new CommentToken(GetSpan(), _sb.ToString(), lines));
                }
            }
예제 #2
0
            /// <summary>
            /// Lex a string or character literal.
            /// </summary>
            private Token LexStrLit()
            {
                char chQuote;

                _sb.Length = 0;
                if (ChCur == '@')
                {
                    chQuote = '"';
                    ChNext();
                    Contracts.Assert(ChCur == '"');
                    ChNext();
                    for (; ;)
                    {
                        char ch = ChCur;
                        if (ch == '"')
                        {
                            ChNext();
                            if (ChCur != '"')
                            {
                                break;
                            }
                            ChNext();
                        }
                        else if (LexCharUtils.IsLineTerm(ch))
                        {
                            ch = LexLineTerm(_sb);
                        }
                        else if (Eof)
                        {
                            ReportError(ErrId.UnterminatedString);
                            break;
                        }
                        else
                        {
                            ChNext();
                        }
                        _sb.Append(ch);
                    }
                }
                else
                {
                    Contracts.Assert(ChCur == '"' || ChCur == '\'');
                    chQuote = ChCur;

                    ChNext();
                    for (; ;)
                    {
                        char ch = ChCur;
                        if (ch == chQuote || Eof || LexCharUtils.IsLineTerm(ch))
                        {
                            break;
                        }
                        if (ch == '\\')
                        {
                            uint u;
                            if (!FLexEscChar(false, out u))
                            {
                                continue;
                            }
                            if (u < 0x10000)
                            {
                                ch = (char)u;
                            }
                            else
                            {
                                char chT;
                                if (!ConvertToSurrogatePair(u, out chT, out ch))
                                {
                                    continue;
                                }
                                _sb.Append(chT);
                            }
                        }
                        else
                        {
                            ChNext();
                        }
                        _sb.Append(ch);
                    }

                    if (ChCur != chQuote)
                    {
                        ReportError(ErrId.NewlineInConst);
                    }
                    else
                    {
                        ChNext();
                    }
                }

                if (chQuote == '"')
                {
                    return(new StrLitToken(GetSpan(), _sb.ToString()));
                }

                if (_sb.Length != 1)
                {
                    ReportError(_sb.Length == 0 ? ErrId.CharConstEmpty : ErrId.CharConstTooLong);
                }
                return(new CharLitToken(GetSpan(), _sb.Length > 0 ? _sb[0] : '\0'));
            }