ANTLR 无法识别错误的关键字
ANTLR doesn't recognize the wrong keyword
我是 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'}"。
问题是什么?非常感谢!
在您的语法中,statement
是 exp
。你的意思可能是 exp ';'
.
正如所写,block
是 statement*
并且可以匹配 exp exp
。由于 ID
是一个 exp
而 double
和 a
都是 ID
,所以 double a
被识别为两个连续的 statement
.
此外,您的语法将 declaration* ';'
识别为 statement
。由于 declaration*
包括零声明的情况——即空字符串——一个单独的 ;
匹配该产生式。我不知道这是否真的是你想要的,但我强烈怀疑你不想匹配两个连续的 declaration
而不用分号分隔它们。
我是 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'}"。 问题是什么?非常感谢!
在您的语法中,statement
是 exp
。你的意思可能是 exp ';'
.
正如所写,block
是 statement*
并且可以匹配 exp exp
。由于 ID
是一个 exp
而 double
和 a
都是 ID
,所以 double a
被识别为两个连续的 statement
.
此外,您的语法将 declaration* ';'
识别为 statement
。由于 declaration*
包括零声明的情况——即空字符串——一个单独的 ;
匹配该产生式。我不知道这是否真的是你想要的,但我强烈怀疑你不想匹配两个连续的 declaration
而不用分号分隔它们。