Parsing 函数式语言解析器如何解析应用程序(expr expr)?

Parsing 函数式语言解析器如何解析应用程序(expr expr)?,parsing,functional-programming,left-recursion,Parsing,Functional Programming,Left Recursion,我最近阅读了一些有关函数式语言编译的文献,我想了解一下如何解析常用的EBNF语法,比如表达式 例如,在带有常数的简单lambda演算中: expr ::= var | literal | 'λ' var '.' expr | expr expr | '(' expr ')' 我关心的是申请expr expr,它是左递归和右递归的。解析器实现者如何解决这个问题?出于这个问题的目的,我主要想知道诸如bison之类的解析器生成器(我知道ANTLR似乎在解决这个问题上做了一些手脚) 有

我最近阅读了一些有关函数式语言编译的文献,我想了解一下如何解析常用的EBNF语法,比如表达式

例如,在带有常数的简单lambda演算中:

expr ::=
   var 
 | literal
 | 'λ' var '.' expr
 | expr expr
 | '(' expr ')'
我关心的是申请
expr expr
,它是左递归和右递归的。解析器实现者如何解决这个问题?出于这个问题的目的,我主要想知道诸如bison之类的解析器生成器(我知道ANTLR似乎在解决这个问题上做了一些手脚)

有可能把这个因素考虑进去吗?是否有一种结构化的方法来解决这种歧义,还是纯粹的启发式?我推测OCaml使用语法分析器生成器,但我还不能对其进行足够的剖析,以了解发生了什么


任何洞察都将不胜感激。

这有帮助吗:?我已经尝试了这两种方法,它们只会导致语法上的巨大变化/减少冲突。整个
%prec ATOM
技巧似乎只有在应用程序看起来像“(fx)”时才能正确地解析应用程序,我试图实现的是:“fx y z”被解析为(((fx)y)z)。我不确定bison是否有足够的能力真正做到这一点。事实上,我只是坐着看一个只读取yyin=stdin的程序,却得到了错误的结果,直到给出了其他标记,才得到“应用”规则。我还没有对它进行大规模测试,看看它是否能处理我想要的语法类型,但我很感谢你对这个问题的回答。优先级“技巧”和第二个语法中的优先级声明主要是关于包含haskell风格的中缀运算符。您可能不关心这些,如果您不忽略相应的产品。我确实同意原子的优先声明有点难看,我认为这在六年前的答案中就已经体现出来了。至于你关于咖喱语法的问题,是的,yacc/bison肯定能够处理这个问题。这并不复杂,C.语法写得不好。如果在另一个共享非终端的语法中间丢弃语法,则可能会发生解析冲突。如果一个或两个语法以一种非平凡的方式依赖于优先级,那么冲突的可能性更大。这是一个阻力,但它不会使CFG无法使用。