使用ANTLR正确检测空白

时间:2012-07-02 18:55:03

标签: java parsing antlr whitespace grammar

我正在使用ANTLR3,通过Maven repo1提供的运行时。

这是我的语法:

grammar MiniJavax;

goal    :   mainClass EOF;

mainClass 
    :    'class' IDENTIFIER '{' methodDeclarations 'public' 'static' 'void' 'main' '(' ')'
    '{' varDeclarations statements '}' '}';

varDeclarations
    :   varDeclaration varDeclarations | ;

varDeclaration
    :   type IDENTIFIER ';' ;

methodDeclarations
    :   methodDeclaration methodDeclarations | ;

methodDeclaration
    :   'public' 'static' type IDENTIFIER '(' parameters ')' '{' varDeclarations statements
        'return' genExpression ';' '}'
    ;

parameters
    :   type IDENTIFIER parameter | ;

parameter 
    :   ',' type IDENTIFIER parameter | ;

type    :   'int' | 'boolean';

statements
    :   statement statements | ;

statement
    :   '{' statements '}'
    |   'if' '(' genExpression ')' statement 'else' statement
    |   'while' '(' genExpression ')' statement
    |   'System' '.' 'out' '.' 'println' '(' genExpression ')' ';'
    |   IDENTIFIER '=' genExpression ';';

genExpression
    :   expression genExpressionRest;

genExpressionRest
    :   relExpression | ;

expression
    :   term expressionRest;

expressionRest
    :   '+' term expressionRest | '-' term expressionRest | ;

term
    :   factor termRest;

termRest 
    :   '*' factor termRest | ;

factor
    :   '(' expression ')'
    |   IDENTIFIER
    |   IDENTIFIER '(' arguments ')'
    |   'true'
    |   'false'
    |   INTEGER;

relExpression
    :   '==' expression relExpressionRest | '<' expression relExpressionRest;

relExpressionRest
    :   '&&' relTerm relExpressionRest |;

relTerm
    :   '==' expression
    |   '<' expression;

arguments
    :   genExpression argument | ;

argument
    :   ',' genExpression argument | ;



IDENTIFIER  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
    ;


INTEGER :   '0'..'9'+
    ;

WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+    { $channel = HIDDEN; } ;

正如您所看到的,我为词法分析器指定了空白字符,并通过HIDDEN通道将其隐藏到解析器中。

但是,当我尝试解析这个时:

class PrintNumbers {
    public static void main() {
        int number;
        number = 1;
        while (number < 11) {
            System.out.println(number);
            number = number + 1;
        }
    }
}

我明白了:

line 1:5 extraneous input ' ' expecting IDENTIFIER

我在这里做错了什么?这不应该能够解决我的问题吗?

顺便说一下,如果改变了什么,我会使用ANTLRWorks生成代码。

更新:为了避免混淆,我已经包含了我的整个语法。

1 个答案:

答案 0 :(得分:0)

碰巧我使用的是BufferedTokenStream而不是通常的CommonTokenStream。这就是为什么频道指令在这里被忽略的原因。