【问题标题】:ANTLR4 parser generation: issue with simple grammar for conditional expressionsANTLR4 解析器生成:条件表达式的简单语法问题
【发布时间】:2018-04-25 03:19:29
【问题描述】:

我正在尝试为一种简单的语言生成词法分析器和解析器。目前,该语言只能解析条件表达式。条件表达式很像 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 )))

我的语法有什么错误?任何帮助表示赞赏。

【问题讨论】:

  • WS 规则不完整。
  • 请不要在您的代码中使用 JS sn-p 包装器,因为您实际上这里没有 JS 代码。
  • @GRosenberg:对不起,WS 规则不完整,因为错字,我现在已经更正了。
  • @MikeLischke:抱歉,感谢您的指正!
  • 对我来说,您的测试输入似乎不符合您的语法 - a 后面应该跟一个运算符。

标签: parsing antlr4


【解决方案1】:

似乎该语法是所需 DSL 的 EBNF 表示的直接实现。需要做更多的工作才能让它在 ANTLR 中正常工作。原样:

1) 规则function_exprparamListparam 存在相互左递归问题;

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 

【讨论】:

  • 谢谢你,并为我迟到的回复道歉。我开始努力改进我的语法,然后看到你的,并开始将你的元素融入我的语法中。最后,您的想法对我有用(尽管我对此的理解仍在进行中),所以我将接受它。只是一个小评论:function 是许多语言中的保留关键字(我的目标 JS 就是其中之一),因此使用不同的解析器名称会更好。我选择了function_expression。简单的修复。谢谢!
猜你喜欢
  • 2014-02-23
  • 2021-12-24
  • 2014-05-07
  • 2020-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-20
  • 2021-10-21
相关资源
最近更新 更多