Example #1
0
        private Token ReadString()
        {
            StartRead();

            char startSymbol = LA(0);

            Consume(); // consume first string character

            while (true)
            {
                char ch = LA(0);
                if (ch == startSymbol)
                {
                    Consume();
                    string tokenData = data.Substring(savePos + 1, pos - savePos - 2);
                    return(CreateToken(TokenType.String, tokenData));
                }
                else if (ch == '\\')
                {
                    if (LA(1) == 'n' || LA(1) == 'r' || LA(1) == '\'' || LA(1) == '"')
                    {
                        // string escape
                        Consume(2);
                        continue;
                    }
                    else
                    {
                        ParserException ex = new ParserException("Unknown escape sequence. Supported escapes: \\n, \\r, \\\", \\'",
                                                                 line, column, pos, 2);
                        ex.Data["code"] = LEXER_ERROR_UNKNOWN_ESCAPE;
                        throw ex;
                    }
                }
                else if (ch == EOF)
                {
                    ParserException ex = new ParserException("Unterminated string constant", saveLine, saveColumn,
                                                             savePos, pos - savePos);
                    ex.Data["code"] = LEXER_ERROR_UNTERMINATED_STRING;
                    throw ex;
                }
                else
                {
                    // consume next string symbol
                    Consume();
                }
            }
        }
Example #2
0
        private Token ReadString()
        {
            StartRead();

            char startSymbol = LA(0);
            Consume(); // consume first string character

            while (true)
            {
                char ch = LA(0);
                if (ch == startSymbol)
                {
                    Consume();
                    string tokenData = data.Substring(savePos + 1, pos - savePos - 2);
                    return CreateToken(TokenType.String, tokenData);
                }
                else if(ch == '\\')
                {
                    if (LA(1) == 'n' || LA(1) == 'r' || LA(1) == '\'' || LA(1) == '"')
                    {
                        // string escape
                        Consume(2);
                        continue;
                    }
                    else
                    {
                        ParserException ex = new ParserException("Unknown escape sequence. Supported escapes: \\n, \\r, \\\", \\'",
                            line, column, pos, 2);
                        ex.Data["code"] = LEXER_ERROR_UNKNOWN_ESCAPE;
                        throw ex;
                    }
                }
                else if (ch == EOF)
                {
                    ParserException ex = new ParserException("Unterminated string constant", saveLine, saveColumn,
                        savePos, pos - savePos);
                    ex.Data["code"] = LEXER_ERROR_UNTERMINATED_STRING;
                    throw ex;
                }
                else
                {
                    // consume next string symbol
                    Consume();
                }
            }
        }
Example #3
0
        private Token ReadExpression()
        {
            StartRead();
        start:
            char ch = LA(0);
            switch (ch)
            {
                case EOF:
                    return CreateToken(TokenType.EOF);
                case ':':
                    Consume();
                    return CreateToken(TokenType.Colon);
                case '.':
                    Consume();
                    return CreateToken(TokenType.Dot);
                case ',':
                    Consume();
                    return CreateToken(TokenType.Comma);
                case '(':
                    Consume();
                    return CreateToken(TokenType.LParen);
                case ')':
                    Consume();
                    return CreateToken(TokenType.RParen);
                case '[':
                    Consume();
                    return CreateToken(TokenType.LBracket);
                case ']':
                    Consume();
                    return CreateToken(TokenType.RBracket);
                case '#': // end of expression
                    Consume();
                    printStart = false;
                    expressionBody = false;
                    return Next();
                case '+':
                    Consume();
                    return CreateToken(TokenType.Plus);
                case '-':
                    Consume();
                    return CreateToken(TokenType.Minus);
                case '*':
                    Consume();
                    return CreateToken(TokenType.Mult);
                case '/':
                    Consume();
                    return CreateToken(TokenType.Div);
                case '%':
                    Consume();
                    return CreateToken(TokenType.Mod);
                case '<':
                    if (LA(1) == '=')
                    {
                        Consume(2);
                        return CreateToken(TokenType.LessOrEqual);
                    }
                    else
                    {
                        Consume();
                        return CreateToken(TokenType.Less);
                    }
                case '>':
                    if (LA(1) == '=')
                    {
                        Consume(2);
                        return CreateToken(TokenType.GreaterOrEqual);
                    }
                    else
                    {
                        Consume();
                        return CreateToken(TokenType.Greater);
                    }
                case '=':
                    if (LA(1) == '=')
                    {
                        Consume(2);
                        return CreateToken(TokenType.Equal);
                    }
                    else
                    {
                        Consume();
                        return CreateToken(TokenType.Assign);
                    }
                case '!':
                    if (LA(1) == '=')
                    {
                        Consume(2);
                        return CreateToken(TokenType.NotEqual);
                    }
                    else
                    {
                        Consume();
                        return CreateToken(TokenType.Not);
                    }
                case '|':
                    if (LA(1) == '|')
                    {
                        Consume(2);
                        return CreateToken(TokenType.Or);
                    }
                    else
                    {
                        Consume();
                        return CreateToken(TokenType.BinOr);
                    }
                case '&':
                    if (LA(1) == '&')
                    {
                        Consume(2);
                        return CreateToken(TokenType.And);
                    }
                    else
                    {
                        Consume();
                        return CreateToken(TokenType.BinAnd);
                    }

                case ' ':
                case '\t':
                case '\r':
                case '\n':
                    ReadWhitespace();
                    goto start;

                case '"':
                case '\'':
                    return ReadString();

                default:
                    if (Char.IsNumber(ch))
                        return ReadNumber();
                    else if (Char.IsLetter(ch) || ch == '_')
                        return ReadIdentifier();
                    else
                    {
                        string symbol = ch.ToString();
                        ParserException ex = new ParserException(String.Format("Unexpected symbol: '{0}'", symbol),
                            saveLine, saveColumn, pos, 1);
                        ex.Data["code"] = LEXER_ERROR_UNEXPECTED_SYMBOL;
                        ex.Data["symbol"] = symbol;
                        throw ex;
                    }
            }
        }
Example #4
0
        private Token ReadTagBody()
        {
            StartRead();
        start:
            char ch = LA(0);
            switch (ch)
            {
                case EOF:
                    return CreateToken(TokenType.EOF);
                case '>':
                    Consume();
                    tagBody = false;
                    return Next();
                case '=':
                    Consume();
                    return CreateToken(TokenType.Assign);
                case ' ':
                case '\t':
                case '\r':
                case '\n':
                    ReadWhitespace();
                    goto start;

                case '"':
                    if (attributeBody)
                    {
                        // end of attribute
                        Consume(); // eat "
                        attributeBody = false;
                    }
                    else
                    {
                        // start of attribute
                        attributeBody = true;
                        if (LA(1) == '#')
                        {
                            Consume(2); // eat "#
                            expressionBody = true;
                            return Next();
                        }
                        else
                        {
                            attributeBody = false;

                            if (Char.IsNumber(LA(1)))
                            {
                                Consume(); // eat "
                                Token num = ReadNumber();
                                Consume(); // eat "
                                return num;
                            }
                            else
                                return ReadString();
                        }
                    }
                    goto start;
                case '\'':
                    return ReadString();

                default:
                    if (ch == '/' && LA(1) == '>')
                    {
                        // "empty" tag
                        Consume(2);
                        tagBody = false;
                        return CreateToken(TokenType.EmptyTag);
                    }
                    else if (Char.IsLetter(ch) || ch == '_')
                    {
                        return ReadAttribute();
                    }
                    else
                    {
                        string symbol = ch.ToString();
                        ParserException ex = new ParserException(String.Format("Unexpected symbol: '{0}'", symbol),
                            saveLine, saveColumn, pos, 1);
                        ex.Data["code"] = LEXER_ERROR_UNEXPECTED_SYMBOL;
                        ex.Data["symbol"] = symbol;
                        throw ex;
                    }
            }
        }
Example #5
0
        private Token ReadExpression()
        {
            StartRead();
start:
            char ch = LA(0);

            switch (ch)
            {
            case EOF:
                return(CreateToken(TokenType.EOF));

            case ':':
                Consume();
                return(CreateToken(TokenType.Colon));

            case '.':
                Consume();
                return(CreateToken(TokenType.Dot));

            case ',':
                Consume();
                return(CreateToken(TokenType.Comma));

            case '(':
                Consume();
                return(CreateToken(TokenType.LParen));

            case ')':
                Consume();
                return(CreateToken(TokenType.RParen));

            case '[':
                Consume();
                return(CreateToken(TokenType.LBracket));

            case ']':
                Consume();
                return(CreateToken(TokenType.RBracket));

            case '#':     // end of expression
                Consume();
                printStart     = false;
                expressionBody = false;
                return(Next());

            case '+':
                Consume();
                return(CreateToken(TokenType.Plus));

            case '-':
                Consume();
                return(CreateToken(TokenType.Minus));

            case '*':
                Consume();
                return(CreateToken(TokenType.Mult));

            case '/':
                Consume();
                return(CreateToken(TokenType.Div));

            case '%':
                Consume();
                return(CreateToken(TokenType.Mod));

            case '<':
                if (LA(1) == '=')
                {
                    Consume(2);
                    return(CreateToken(TokenType.LessOrEqual));
                }
                else
                {
                    Consume();
                    return(CreateToken(TokenType.Less));
                }

            case '>':
                if (LA(1) == '=')
                {
                    Consume(2);
                    return(CreateToken(TokenType.GreaterOrEqual));
                }
                else
                {
                    Consume();
                    return(CreateToken(TokenType.Greater));
                }

            case '=':
                if (LA(1) == '=')
                {
                    Consume(2);
                    return(CreateToken(TokenType.Equal));
                }
                else
                {
                    Consume();
                    return(CreateToken(TokenType.Assign));
                }

            case '!':
                if (LA(1) == '=')
                {
                    Consume(2);
                    return(CreateToken(TokenType.NotEqual));
                }
                else
                {
                    Consume();
                    return(CreateToken(TokenType.Not));
                }

            case '|':
                if (LA(1) == '|')
                {
                    Consume(2);
                    return(CreateToken(TokenType.Or));
                }
                else
                {
                    Consume();
                    return(CreateToken(TokenType.BinOr));
                }

            case '&':
                if (LA(1) == '&')
                {
                    Consume(2);
                    return(CreateToken(TokenType.And));
                }
                else
                {
                    Consume();
                    return(CreateToken(TokenType.BinAnd));
                }

            case ' ':
            case '\t':
            case '\r':
            case '\n':
                ReadWhitespace();
                goto start;

            case '"':
            case '\'':
                return(ReadString());

            default:
                if (Char.IsNumber(ch))
                {
                    return(ReadNumber());
                }
                else if (Char.IsLetter(ch) || ch == '_')
                {
                    return(ReadIdentifier());
                }
                else
                {
                    string          symbol = ch.ToString();
                    ParserException ex     = new ParserException(String.Format("Unexpected symbol: '{0}'", symbol),
                                                                 saveLine, saveColumn, pos, 1);
                    ex.Data["code"]   = LEXER_ERROR_UNEXPECTED_SYMBOL;
                    ex.Data["symbol"] = symbol;
                    throw ex;
                }
            }
        }
Example #6
0
        private Token ReadTagBody()
        {
            StartRead();
start:
            char ch = LA(0);

            switch (ch)
            {
            case EOF:
                return(CreateToken(TokenType.EOF));

            case '>':
                Consume();
                tagBody = false;
                return(Next());

            case '=':
                Consume();
                return(CreateToken(TokenType.Assign));

            case ' ':
            case '\t':
            case '\r':
            case '\n':
                ReadWhitespace();
                goto start;

            case '"':
                if (attributeBody)
                {
                    // end of attribute
                    Consume();     // eat "
                    attributeBody = false;
                }
                else
                {
                    // start of attribute
                    attributeBody = true;
                    if (LA(1) == '#')
                    {
                        Consume(2);     // eat "#
                        expressionBody = true;
                        return(Next());
                    }
                    else
                    {
                        attributeBody = false;

                        if (Char.IsNumber(LA(1)))
                        {
                            Consume();     // eat "
                            Token num = ReadNumber();
                            Consume();     // eat "
                            return(num);
                        }
                        else
                        {
                            return(ReadString());
                        }
                    }
                }
                goto start;

            case '\'':
                return(ReadString());

            default:
                if (ch == '/' && LA(1) == '>')
                {
                    // "empty" tag
                    Consume(2);
                    tagBody = false;
                    return(CreateToken(TokenType.EmptyTag));
                }
                else if (Char.IsLetter(ch) || ch == '_')
                {
                    return(ReadAttribute());
                }
                else
                {
                    string          symbol = ch.ToString();
                    ParserException ex     = new ParserException(String.Format("Unexpected symbol: '{0}'", symbol),
                                                                 saveLine, saveColumn, pos, 1);
                    ex.Data["code"]   = LEXER_ERROR_UNEXPECTED_SYMBOL;
                    ex.Data["symbol"] = symbol;
                    throw ex;
                }
            }
        }