recursion - 如何消除左递归

标签 recursion antlr antlr3 left-recursion

我想创建一个允许柯里化(Currying)函数调用的语法。

即:

a() /// good
a()() /// good
a()()() /// good
a(a) /// good
a(a()()) /// good
/// etc

我的第一次尝试是这样的:

ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;

fncall  :   expr '(' (expr (',' expr)*)? ')';

expr    :   ID|fncall;

但是由于左递归而失败。

最佳答案

假设(a)()也有效,这里有一个解决这个问题的方法:

grammar T;

options {
  output=AST;
}

tokens {
  EXPR_LIST;
  CALL;
  INDEX;
  LOOKUP;
}

parse
 : expr EOF -> expr
 ;

expr
 : add_expr
 ;

add_expr
 : mul_exp (('+' | '-')^ mul_exp)*
 ;

mul_exp 
 : atom (('*' | '/')^ atom)*
 ;

atom
 : fncall
 | NUM
 ;

fncall
 : (fncall_start -> fncall_start) ( '(' expr_list ')' -> ^(CALL $fncall expr_list)
                                  | '[' expr ']'      -> ^(INDEX $fncall expr)
                                  | '.' ID            -> ^(LOOKUP $fncall ID)
                                  )* 
 ;

fncall_start
 : ID
 | '(' expr ')' -> expr
 ;

expr_list
 : (expr (',' expr)*)? -> ^(EXPR_LIST expr*)
 ;

NUM : '0'..'9'+;
ID  :  ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;

从上面的语法生成的解析器将解析输入:

(foo.bar().array[i*2])(42)(1,2,3)

并构造以下 AST:

enter image description here

如果没有树重写规则,语法将如下所示:

grammar T;

parse
 : expr EOF
 ;

expr
 : add_expr
 ;

add_expr
 : mul_exp (('+' | '-') mul_exp)*
 ;

mul_exp 
 : atom (('*' | '/') atom)*
 ;

atom
 : fncall
 | NUM
 ;

fncall
 : fncall_start ( '(' expr_list ')' | '[' expr ']' | '.' ID )* 
 ;

fncall_start
 : ID
 | '(' expr ')'
 ;

expr_list
 : (expr (',' expr)*)?
 ;

NUM : '0'..'9'+;
ID  :  ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;

关于recursion - 如何消除左递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10508273/

相关文章:

c - 什么是 Antlr3 C 运行时等效于抛出错误报告的异常

c - 需要算法方面的帮助(堆栈溢出)

php - PHP这里如何避免无限递归?

java - 无法理解递归如何与数独求解器一起工作

c - 下面的递归方法如何与 (i++,i) 括起来的参数一起使用?谁能解释一下吗?

java - Antlr4 - 获取函数的参数 Java

c# - C# 的 Antlr.Runtime 中缺少类

java - 左递归: ANTLR

antlr3 - 使用 Antlr-3.5-complete.jar 生成 OracleSQL 语法时出现大量模板错误

antlr - ANTLR 词法分析器中的特殊字符处理