【问题标题】:ANTLR doesn't recognize the wrong keywordANTLR 无法识别错误的关键字
【发布时间】:2019-03-29 15:11:36
【问题描述】:

我是 ANTLR 的菜鸟。我正在为一种简单的语言构建编译器,但我不明白为什么,如果我写错了键盘,编译器不会给我正确的错误。

这是我的语法:

            grammar Exercise;

            block  : '{' statement* '}';

            statement : assignment ';' 
                      | deletion ';' 
                      | print ';'
                      | declaration* ';'
                      | ifStat
                      | functionDecl
                      | exp
                      | block+
                      ;


            assignment : ID '=' exp;

            type  : 'int'
                  | 'boolean'
                  ;

            typeF  : 'void' ;


            declaration : type ID ;

            deletion : 'delete' ID;

            print  : 'print' exp;

            bool  : 'true' 
                  | 'false' 
                  ;

            exp : '(' exp ')'   
                | ID '(' expList? ')'
                | NUMBER 
                | bool
                | ID
                ;

            expIF   : ID EQ ID
                    | ID EQ bool
                    | ID GT ID
                    | ID LT ID
                    | ID NEQ ID 
                    | ID GTEQ ID
                    | ID LTEQ ID
                    | NOT ID
                    | ID 
                    ;

            ifStat  : 'if' '('expIF')' 'then' block ('else' block)? ;

            formalParameter  : declaration 
                             | rif declaration
                             ;

            rif : 'var';

            formalParameters    : formalParameter (',' formalParameter)* ; 

            functionDecl    : typeF ID LPAR formalParameters? RPAR block ; 

            expList : ID (',' ID )* ; 

            //IDs
            fragment CHAR  : 'a'..'z' |'A'..'Z' ;
            ID              : (CHAR)+ | (DIGIT)+ ;

            //Numbers
            fragment DIGIT : '0'..'9'; 
            NUMBER          : DIGIT+;

            OR : '||';
            AND : '&&';
            NOT : '!';
            EQ : '==';
            NEQ : '!=';
            GT : '>';
            LT : '<';
            GTEQ : '>=';
            LTEQ : '<=';
            LPAR : '(';
            RPAR : ')';

            //ESCAPE SEQUENCES
            WS              : (' '|'\t'|'\n'|'\r')-> skip;
            LINECOMMENTS  : '//' (~('\n'|'\r'))* -> skip;
            BLOCKCOMMENTS    : '/*'( ~('/'|'*')|'/'~'*'|'*'~'/'|BLOCKCOMMENTS)* '*/' -> skip;
            ERR: . -> channel(HIDDEN);

这是我的主要内容:

   public static void main(String[] args) {

   //create lexer

       ExerciseLexer lexer = new ExerciseLexer(new ANTLRInputStream("{ double a ;  boolean d; a = 4 ; {boolean d ; int a} int s;}") );

   //create parser
       CommonTokenStream tokens = new CommonTokenStream(lexer);
       ExerciseParser parser = new ExerciseParser(tokens);

   //tell the parser to build the AST
        parser.setBuildParseTree(true);

    //build custom visitor
        ExerciseVisitorImpl visitor = new ExerciseVisitorImpl();
        ParseTree pt = parser.block();
        visitor.visit(pt);  

例如,在这种情况下,我应该得到“double”关键字的错误,但我得到“line 1:51 extraneous input '}' expecting {'boolean', ';', 'int'}” . 问题是什么?非常感谢!

【问题讨论】:

  • 您的 ID 规则看起来有问题。它将匹配abc(所有字母)或123(所有数字),但不匹配abc123。此外,您的 NUMBER 规则永远不会匹配任何内容,因为它可以匹配的任何内容都已经被 ID 匹配。
  • 我也会重新考虑expIF 规则。按原样,您只能将标识符相互比较或ID == bool(但不能ID != bool)或直接使用变量作为条件。但是,您无法将任何内容与数字常量进行比较(至少没有一次 NUMBER 正确匹配它们),您不能将函数调用用作条件或比较任何其他类型的东西。您也不能否定变量以外的条件。我建议改为允许任意表达式作为比较运算符的操作数,并将 expexpIf 合并到一个规则中(通常是这样做的)。
  • 你是对的!感谢您的建议!

标签: compiler-construction antlr antlr4 compiler-optimization


【解决方案1】:

在您的语法中,statementexp。你的意思可能是exp ';'

正如所写,blockstatement*,可以匹配 exp exp。由于IDexpdoublea 都是IDs,double a 被识别为两个连续的statements。

此外,您的语法将declaration* ';' 识别为statement。由于declaration* 包括零声明的情况——即空字符串——一个单独的; 匹配该产生式。我不知道这是否真的是您想要的,但我强烈怀疑您不想匹配两个连续的 declaration 而不用分号分隔它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-09
    • 2023-02-04
    • 2018-02-25
    • 2018-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多