Antlr4无法识别关键字并将其分类为标识符(ID)。

huangapple go评论78阅读模式
英文:

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'关键字正在期望,并且当我查看解析树时,它将ANDOR分类为ID,而ifelse部分不在树中。指示期望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                :   &#39;if&#39;;
THEN              :   &#39;then&#39;;
ELSE              :   &#39;else&#39;;
ELSE_IF           :   &#39;else if&#39;;
END_IF            :   &#39;end if&#39;;
DECLARE : &#39;declare&#39;;
SET : &#39;set&#39;;
TO : &#39;to&#39;;
SHOW : &#39;show&#39;;
ID : [a-zA-Z] [a-zA-Z0-9_]*;
NUMBER : (&#39;+&#39; | &#39;-&#39;)? [0-9]+ (&#39;.&#39; [0-9]+)?;
STRING : &#39;&quot;&#39; ( &#39;\\&#39; . | ~[\\&quot;] )* &#39;&quot;&#39; | &#39;\&#39;&#39; ( &#39;\\&#39; . | ~[\\&#39;] )* &#39;\&#39;&#39; ;
INPUT  : &#39;input&#39;;
MUL : &#39;*&#39;;
DIV : &#39;/&#39;;
MODULO : &#39;remind&#39;;
POW    : &#39;^&#39;;
PLUS : &#39;+&#39;;
MINUS : &#39;-&#39;;
SEMICOLON : &#39;;&#39;;
LPAREN : &#39;(&#39;;
RPAREN : &#39;)&#39;;
AND : &#39;and&#39;;
OR : &#39;or&#39;;
NOT : &#39;not&#39;;
LESS_THAN         :   &#39;&lt;&#39;;
LESS_THAN_EQUAL   :   &#39;&lt;=&#39;;
GREATER_THAN      :   &#39;&gt;&#39;;
GREATER_THAN_EQUAL:   &#39;&gt;=&#39;;
EQUAL             :   &#39;==&#39;;
NOT_EQUAL         :   &#39;!=&#39;;
NEWLINE : &#39;\r&#39;? &#39;\n&#39;;
WS : [ \t\n\r]+ -&gt; 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 (&#39;^&#39; 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 &lt; y and y &gt;= z or x == y then
  show(&quot;x is less than y and y is greater than or equal to z, or x is not equal to y&quot;)
else
  show(&quot;none of the above&quot;)
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  : &#39;input&#39;;

ANTLR will never create an INPUT because the source &quot;input&quot; wil always become an ID token. The solution: place INPUT (and all other keywords!) above the ID rule:

INPUT  : &#39;input&#39;;
ID : [a-zA-Z] [a-zA-Z0-9_]*;

Of course, this will cause &quot;input&quot; 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

huangapple
  • 本文由 发表于 2023年3月8日 17:29:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/75671329.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定