ANTLR4 解析器生成:条件表达式的简单语法问题
ANTLR4 parser generation: issue with simple grammar for conditional expressions
我正在尝试为一种简单的语言生成词法分析器和解析器。目前,该语言只能解析条件表达式。条件表达式与 C 中的非常相似,因为我在这里只学习基本知识,所以我们在 C 等语言中遇到的所有问题我都不会关心实现。
我有以下语法:
grammar Simple ;
cond_expr : left_paren operand operator operand right_paren ;
operand : function_expr | ID | literal | cond_expr ;
function_expr : ID left_paren paramList right_paren ;
paramList : param (',' param)* ;
param : ID | function_expr ;
literal : string | number ;
string : '"' sentence '"' ;
sentence : (WORD | WORD (' ' WORD)*)* ;
number : INTEGER | FLOAT ;
left_paren : LEFT_PAREN ;
right_paren : RIGHT_PAREN ;
operator : OPERATOR ;
INTEGER : [0-9]+ ;
FLOAT : INTEGER '.' INTEGER | '.' INTEGER ;
LEFT_PAREN : '(' ;
RIGHT_PAREN : ')' ;
ID : [A-Za-z]+[A-Za-z0-9_]* ;
WORD : [A-Za-z]+ ;
OPERATOR : ('==' | '>=' | '<=' | '!=' | '&&' | '||' | '~') ;
WS : (' '|'\r'|'\n'|'\t') -> channel(HIDDEN);
当我 运行 解析器时,我没有得到我期望的结果。这是一个错误输出的例子:
~/sandbox $ grun Simple cond_expr -tree
(a (c, d (e, f)) != b)
line 1:2 mismatched input ' ' expecting OPERATOR
line 1:5 mismatched input ',' expecting OPERATOR
line 1:8 mismatched input ' ' expecting ')'
(cond_expr (left_paren () (operand a) (operator ) (operand (cond_expr (left_paren () (operand c) (operator , ) (operand d) (right_paren ( e , f))) (right_paren )))
我的语法有什么错误?感谢任何帮助。
似乎语法是所需 DSL 的 EBNF 表示的直接实现。需要做更多的工作才能让它在 ANTLR 中正常工作。原样:
1)规则function_expr
、paramList
、param
;
存在互左递归问题
2) sentence
什么都不匹配;
3) WS
隐藏在词法分析器中,所以 sentence
无论如何都无法匹配 ;);
4) ID
规则影响 WORD
,所以 WORD
令牌永远不会被发出。
(您应该在 1 和 2 上收到工具警告;切勿忽略,因为警告表明 运行 时间行为 可能 受到影响。)
表达式规则的基本形式是在单个规则中列出表达式的所有替代形式。
expr : LPAREN expr RPAREN
| expr operator expr
| function
| string
| number
| ID
;
function : ID LPAREN ( ID | function ) (',' ( ID | function ))* RPAREN ;
string : STRING ;
number : INTEGER | FLOAT ;
operator : OPERATOR ;
STRING : '"' .*? '"' ;
(未经测试)
所以 (a (c, d (e, f)) != b)
应该正确计算为
expr (function ( ID, function ( ID, ID ) ) operator ID
我正在尝试为一种简单的语言生成词法分析器和解析器。目前,该语言只能解析条件表达式。条件表达式与 C 中的非常相似,因为我在这里只学习基本知识,所以我们在 C 等语言中遇到的所有问题我都不会关心实现。
我有以下语法:
grammar Simple ;
cond_expr : left_paren operand operator operand right_paren ;
operand : function_expr | ID | literal | cond_expr ;
function_expr : ID left_paren paramList right_paren ;
paramList : param (',' param)* ;
param : ID | function_expr ;
literal : string | number ;
string : '"' sentence '"' ;
sentence : (WORD | WORD (' ' WORD)*)* ;
number : INTEGER | FLOAT ;
left_paren : LEFT_PAREN ;
right_paren : RIGHT_PAREN ;
operator : OPERATOR ;
INTEGER : [0-9]+ ;
FLOAT : INTEGER '.' INTEGER | '.' INTEGER ;
LEFT_PAREN : '(' ;
RIGHT_PAREN : ')' ;
ID : [A-Za-z]+[A-Za-z0-9_]* ;
WORD : [A-Za-z]+ ;
OPERATOR : ('==' | '>=' | '<=' | '!=' | '&&' | '||' | '~') ;
WS : (' '|'\r'|'\n'|'\t') -> channel(HIDDEN);
当我 运行 解析器时,我没有得到我期望的结果。这是一个错误输出的例子:
~/sandbox $ grun Simple cond_expr -tree
(a (c, d (e, f)) != b)
line 1:2 mismatched input ' ' expecting OPERATOR
line 1:5 mismatched input ',' expecting OPERATOR
line 1:8 mismatched input ' ' expecting ')'
(cond_expr (left_paren () (operand a) (operator ) (operand (cond_expr (left_paren () (operand c) (operator , ) (operand d) (right_paren ( e , f))) (right_paren )))
我的语法有什么错误?感谢任何帮助。
似乎语法是所需 DSL 的 EBNF 表示的直接实现。需要做更多的工作才能让它在 ANTLR 中正常工作。原样:
1)规则function_expr
、paramList
、param
;
存在互左递归问题
2) sentence
什么都不匹配;
3) WS
隐藏在词法分析器中,所以 sentence
无论如何都无法匹配 ;);
4) ID
规则影响 WORD
,所以 WORD
令牌永远不会被发出。
(您应该在 1 和 2 上收到工具警告;切勿忽略,因为警告表明 运行 时间行为 可能 受到影响。)
表达式规则的基本形式是在单个规则中列出表达式的所有替代形式。
expr : LPAREN expr RPAREN
| expr operator expr
| function
| string
| number
| ID
;
function : ID LPAREN ( ID | function ) (',' ( ID | function ))* RPAREN ;
string : STRING ;
number : INTEGER | FLOAT ;
operator : OPERATOR ;
STRING : '"' .*? '"' ;
(未经测试)
所以 (a (c, d (e, f)) != b)
应该正确计算为
expr (function ( ID, function ( ID, ID ) ) operator ID