不匹配的输入antlr4错误解释

时间:2014-03-25 22:22:08

标签: parsing antlr antlr4 lexer

我被大学的编译器项目困住了,无法解析以下输入

haupt() {
    while(i==2) {
        (5+2)*3
        }
}

用这个语法:

grammar Demo;

@header {
    import java.util.List;
    import java.util.ArrayList;
}

program:
    functionList
    ;

functionList:
    function*
    ;

function:
    'haupt()' '{' stmntList '}'                 #haupt
    |'Integer' ID '(' paramList ')' '{' stmntList '}'   #integerFunction
    | 'String' ID '(' paramList ')' '{' stmntList '}'   #stringFunction
    | 'void' ID '(' paramList ')' '{' stmntList '}'     #voidFunction
    ;

paramList:
    param (',' paramList)?
    ;

param:
    'Integer' ID                                        
    | 'String' ID                                       
    ;

variableList:
    ID (',' variableList)?
    ;


stmntList:
    stmnt (stmntList)?                                      
    ;

stmnt:
    'Integer' ID ';'                                                        #integerStmnt
    | 'String' ID   ';'                                                     #stringStmnt
    |  ID '=' expr  ';'                                                     #varAssignment
    | 'print''(' ID ')'     ';'                                             #printText
    | 'toString' '(' ID ')'';'                                              #convertString
    | 'toInteger''('ID')'';'                                                #convertInteger
    | 'if' '(' boolExpr ')' '{' stmntList '}'  ('else' '{' stmntList '}')?  #elseStmnt  
    | 'for' '(' ID '=' expr ',' boolExpr ',' stmnt ')' '{' stmntList '}'    #forLoop    
    | 'while' '(' boolExpr ')' '{' stmntList '}'                            #whileLoop
    | 'do' '{' stmntList '}' 'while' '(' boolExpr ')'   ';'                 #doWhile
    | 'return' expr             ';'                                         #returnVar
    | ID '(' variableList ')'';'                                            #functionCall               
    ;

boolExpr:
    boolParts ('&&' boolExpr)?                  #logicAnd
    | boolParts ('||' boolExpr)?                #logicOr
    ;

boolParts:
    expr '==' expr                      #isEqual
    | expr '!=' expr                    #isUnequal
    | expr '>' expr                     #biggerThan
    | expr '<' expr                     #smallerThan
    | expr '>=' expr                    #biggerEqual
    | expr '<=' expr                    #smallerEqual
    ;

expr:
    links=expr '+' rechts=product                   #addi
    | links = expr '-' rechts=product               #diff
    |product                            #prod
    ;

product:
    links=product '*' rechts=factor                 #mult
    | links=product '/' rechts=factor               #teil
    | factor                            #fact
    ;

factor:
    '(' expr')'                         #bracket
    | ID                                #var
    | zahl=NUMBER                           #numb
    ;


ID  :       [a-zA-Z]*;
NUMBER  :   '0'|[1-9][0-9]*;
WS:         [\r\n\t ]+ -> skip ;

因为我收到以下错误消息:

line 1:5: mismatched input '(' expecting {<EOF>, '-', '*', '+', '/'}

我认为antlr误解了输入并认为&#34; haupt&#34;是一个ID而不是第一个功能规则。怎么会发生这种情况?我一直认为antlr使用第一个规则匹配?

感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

我会按照建议使用'haupt''('')',但'haupt()'应匹配。事实上确实如此。我得到的错误在第3行。语句中没有任何内容匹配(5 + 2)* 3。

答案 1 :(得分:0)

我得到了一个不同的错误:

line 3:8 no viable alternative at input '('

我可以解释一下:(5 + 2)* 3没有声明(正如Ter已经指出的那样)。

你似乎使用了一个奇怪版本的ANTLR ......

您还应注意警告:

warning(146): Path\To\File\Demo.g4:95:0: non-fragment lexer rule 'ID' can match the empty string

这告诉你空字符串也是一个标识符(在大多数情况下不是你想要的)。将*更改为+有助于...

答案 2 :(得分:0)

关于comment

它适用于我(请注意,ID规则与您的版本稍有不同,但它也适用于您的版本)。

如果您查看令牌类型(<>中的数字),您会看到printabc的类型(即ID )是不同的(17('print')和33(ID))。

语法:

grammar Demo;

@header {
    import java.util.List;
    import java.util.ArrayList;
}

program:
    functionList
    ;

functionList:
    function*
    ;

function:
    'haupt()' '{' stmntList '}'                 #haupt
    |'Integer' ID '(' paramList ')' '{' stmntList '}'   #integerFunction
    | 'String' ID '(' paramList ')' '{' stmntList '}'   #stringFunction
    | 'void' ID '(' paramList ')' '{' stmntList '}'     #voidFunction
    ;

paramList:
    param (',' paramList)?
    ;

param:
    'Integer' ID
    | 'String' ID
    ;

variableList:
    ID (',' variableList)?
    ;


stmntList:
    stmnt (stmntList)?
    ;

stmnt:
    'Integer' ID ';'                                                        #integerStmnt
    | 'String' ID   ';'                                                     #stringStmnt
    |  ID '=' expr  ';'                                                     #varAssignment
    | 'print''(' ID ')'     ';'                                             #printText
    | 'toString' '(' ID ')'';'                                              #convertString
    | 'toInteger''('ID')'';'                                                #convertInteger
    | 'if' '(' boolExpr ')' '{' stmntList '}'  ('else' '{' stmntList '}')?  #elseStmnt
    | 'for' '(' ID '=' expr ',' boolExpr ',' stmnt ')' '{' stmntList '}'    #forLoop
    | 'while' '(' boolExpr ')' '{' stmntList '}'                            #whileLoop
    | 'do' '{' stmntList '}' 'while' '(' boolExpr ')'   ';'                 #doWhile
    | 'return' expr             ';'                                         #returnVar
    | ID '(' variableList ')'';'                                            #functionCall
    ;

boolExpr:
    boolParts ('&&' boolExpr)?                  #logicAnd
    | boolParts ('||' boolExpr)?                #logicOr
    ;

boolParts:
    expr '==' expr                      #isEqual
    | expr '!=' expr                    #isUnequal
    | expr '>' expr                     #biggerThan
    | expr '<' expr                     #smallerThan
    | expr '>=' expr                    #biggerEqual
    | expr '<=' expr                    #smallerEqual
    ;

expr:
    links=expr '+' rechts=product                   #addi
    | links = expr '-' rechts=product               #diff
    |product                            #prod
    ;

product:
    links=product '*' rechts=factor                 #mult
    | links=product '/' rechts=factor               #teil
    | factor                            #fact
    ;

factor:
    '(' expr')'                         #bracket
    | ID                                #var
    | zahl=NUMBER                           #numb
    ;


ID  :       [a-zA-Z]+;
NUMBER  :   '0'|[1-9][0-9]*;
WS:         [\r\n\t ]+ -> skip ;

测试文件:

haupt() {
    while(i==2) {
        print(abc);
        }
}

结果:

[@0,0:6='haupt()',<18>,1:0]
[@1,8:8='{',<9>,1:8]
[@2,14:18='while',<6>,2:4]
[@3,19:19='(',<20>,2:9]
[@4,20:20='i',<33>,2:10]
[@5,21:22='==',<25>,2:11]
[@6,23:23='2',<34>,2:13]
[@7,24:24=')',<30>,2:14]
[@8,26:26='{',<9>,2:16]
[@9,36:40='print',<17>,3:8]
[@10,41:41='(',<20>,3:13]
[@11,42:44='abc',<33>,3:14]
[@12,45:45=')',<30>,3:17]
[@13,46:46=';',<7>,3:18]
[@14,56:56='}',<13>,4:8]
[@15,58:58='}',<13>,5:0]
[@16,59:58='<EOF>',<-1>,5:1]
(program (functionList (function haupt() { (stmntList (stmnt while ( (boolExpr (boolParts (expr (product (factor i))) == (expr (product (factor 2))))) ) { (stmntList (stmnt print ( abc ) ;)) })) })))

Parse tree

相关问题