英文:
Antlr4 is not recognizing Keywords and classifying them as ID
问题
我一直在互联网上搜索了近3天,但找不到解决方案,请帮忙。
以下是问题:
我有这个语法:
grammar EasyBite;
IF : 'if';
THEN : 'then';
ELSE : 'else';
ELSE_IF : 'else if';
END_IF : 'end if';
DECLARE : 'declare';
SET : 'set';
TO : 'to';
SHOW : 'show';
ID : [a-zA-Z] [a-zA-Z0-9_]*;
NUMBER : ('+' | '-')? [0-9]+ ('.' [0-9]+)?;
STRING : '"' ( '\\' . | ~['"] )* '"';
INPUT : 'input';
MUL : '*';
DIV : '/';
MODULO : 'remind';
POW : '^';
PLUS : '+';
MINUS : '-';
SEMICOLON : ';';
LPAREN : '(';
RPAREN : ')';
AND : 'and';
OR : 'or';
NOT : 'not';
LESS_THAN : '<';
LESS_THAN_EQUAL : '<=';
GREATER_THAN : '>';
GREATER_THAN_EQUAL: '>=';
EQUAL : '==';
NOT_EQUAL : '!=';
NEWLINE : '\r'? '\n';
WS : [ \t\n\r]+ -> skip;
// Parser rule
program : statement_list* | EOF;
statement_list : statement (NEWLINE|SEMICOLON)*;
statement : if_statement
|declare_statement
|set_statement
|input_statement
|print_statement
;
// Declaration statement
if_statement : IF expression THEN statement_list (elseif_statement)* (ELSE statement_list)? END_IF;
elseif_statement : ELSE_IF expression THEN statement_list;
declare_statement : DECLARE ID;
set_statement : (SET ID | ID) TO expression | value | comparison;
input_statement : (SET ID | ID) TO INPUT LPAREN expression RPAREN;
print_statement : SHOW (LPAREN expression RPAREN | STRING);
expression: logicalOr;
logicalOr: logicalAnd (OR logicalAnd)*;
logicalAnd: equality (AND equality)*;
comparison: equality ((GREATER_THAN | LESS_THAN | GREATER_THAN_EQUAL | LESS_THAN_EQUAL) equality)*;
equality: term ((EQUAL | NOT_EQUAL) term)*;
term: factor ((PLUS | MINUS) factor)*;
factor: power ((MUL | DIV | MODULO) power)*;
power: value ('^' value)*;
value: NUMBER | STRING | ID;
我正在使用Intellij Idea验证解析树,它现在指示'then
'关键字正在期望,并且当我查看解析树时,它将AND
和OR
分类为ID
,而if
的else
部分不在树中。指示期望LESS_THAN
。
以下是我尝试了语法的源代码:
declare x
set x to 10
declare y
set y to 20
declare z
set z to x + y * 2
if x < y and y >= z or x == y then
show("x is less than y and y is greater than or equal to z, or x is not equal to y")
else
show("none of the above")
end if
以下是树的输出 The tree output。很抱歉,我无法在这里添加内联链接。
如果可能的话,我需要一个能够实现预期功能的语法,以及问题的原因和解决方案。请帮忙。
英文:
I have been searching the internet for almost 3 days now i cant find solution, please Help
Here is the problem
I Have this grammar
grammar EasyBite;
IF : 'if';
THEN : 'then';
ELSE : 'else';
ELSE_IF : 'else if';
END_IF : 'end if';
DECLARE : 'declare';
SET : 'set';
TO : 'to';
SHOW : 'show';
ID : [a-zA-Z] [a-zA-Z0-9_]*;
NUMBER : ('+' | '-')? [0-9]+ ('.' [0-9]+)?;
STRING : '"' ( '\\' . | ~[\\"] )* '"' | '\'' ( '\\' . | ~[\\'] )* '\'' ;
INPUT : 'input';
MUL : '*';
DIV : '/';
MODULO : 'remind';
POW : '^';
PLUS : '+';
MINUS : '-';
SEMICOLON : ';';
LPAREN : '(';
RPAREN : ')';
AND : 'and';
OR : 'or';
NOT : 'not';
LESS_THAN : '<';
LESS_THAN_EQUAL : '<=';
GREATER_THAN : '>';
GREATER_THAN_EQUAL: '>=';
EQUAL : '==';
NOT_EQUAL : '!=';
NEWLINE : '\r'? '\n';
WS : [ \t\n\r]+ -> skip;
// Parser rule
program : statement_list* | EOF;
statement_list : statement (NEWLINE|SEMICOLON)*;
statement : if_statement
|declare_statement
|set_statement
|input_statement
|print_statement
;
// Declaration statement
if_statement : IF expression THEN statement_list (elseif_statement)* (ELSE statement_list)? END_IF;
elseif_statement : ELSE_IF expression THEN statement_list;
declare_statement : DECLARE ID;
set_statement : (SET ID | ID) TO expression | value | comparison;
input_statement : (SET ID | ID) TO INPUT LPAREN expression RPAREN;
print_statement : SHOW (LPAREN expression RPAREN | STRING);
expression: logicalOr;
logicalOr: logicalAnd (OR logicalAnd)*;
logicalAnd: equality (AND equality)*;
comparison: equality ((GREATER_THAN | LESS_THAN | GREATER_THAN_EQUAL | LESS_THAN_EQUAL) equality)*;
equality: term ((EQUAL | NOT_EQUAL) term)*;
term: factor ((PLUS | MINUS) factor)*;
factor: power ((MUL | DIV | MODULO) power)*;
power: value ('^' value)*;
value: NUMBER | STRING | ID;
I am using Intellij Idea to verify the parse tree, it now indicating 'then' keyword is expecting, and when i went through the parse tree, it classifying AND and OR
as ID also else part of if is not in the tree. Indicating LESS_THAN is expected.
Here is source i tried the grammar with
declare x
set x to 10
declare y
set y to 20
declare z
set z to x + y * 2
if x < y and y >= z or x == y then
show("x is less than y and y is greater than or equal to z, or x is not equal to y")
else
show("none of the above")
end if
Below is the Tree output
The tree output
I dont know how add it inline.
Thank you.
If possible, i need a grammar that will do what intended and cause of the problem and solution.
Please help.
答案1
得分: 1
以下是翻译好的内容:
您的词法规则的顺序很重要。考虑以下规则:
ID : [a-zA-Z] [a-zA-Z0-9_]*;
INPUT : 'input';
ANTLR 永远不会创建一个 `INPUT`,因为源代码中的 "input" 总是会变成一个 `ID` 标记。解决方案是:将 `INPUT`(以及所有其他关键字!)放在 `ID` 规则上面:
INPUT : 'input';
ID : [a-zA-Z] [a-zA-Z0-9_]*;
当然,这会导致 "input" 永远不会成为一个 `ID` 标记。如果您希望关键字也成为标识符,请参考这个问答页面:https://stackoverflow.com/questions/41421644/antlr4-how-to-build-a-grammar-allowed-keywords-as-identifier
英文:
The order of your lexer rule matter. Given these rules:
ID : [a-zA-Z] [a-zA-Z0-9_]*;
INPUT : 'input';
ANTLR will never create an INPUT
because the source "input"
wil always become an ID
token. The solution: place INPUT
(and all other keywords!) above the ID
rule:
INPUT : 'input';
ID : [a-zA-Z] [a-zA-Z0-9_]*;
Of course, this will cause "input"
to never become an ID
token. If you want keywords to become identifiers as well, have a look at this Q&A: https://stackoverflow.com/questions/41421644/antlr4-how-to-build-a-grammar-allowed-keywords-as-identifier
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论