在使用快乐解析器编写的函数式语言编译器中,这与 yacc/bison 非常相似,我实现了列表和列表一些核心函数map
,concat
并且filter
,使用以下规则:
Exp:
...
| concat '(' Exp ',' Exp ')' { Concat $3 $5 }
| map '(' Exp ',' Exp ')' { Map $3 $5 }
| filter '(' Exp ',' Exp ')' { Filter $3 $5 }
这很好用,但在大多数函数式语言中没有括号或逗号,所以map(myfun, [1,2,3])
我宁愿写map myfun [1,2,3]
. 语法中明显的修改如下:
Exp:
...
| concat Exp Exp { Concat $2 $3 }
| map Exp Exp { Map $2 $3 }
| filter Exp Exp { Filter $2 $3 }
但是这个修改包含很多reduce-reduce 冲突。如何在没有逗号和括号的情况下实现函数调用的解析?
我能提取的最小的冲突语法是这样的:
Exp :
-- Math
Exp '+' Exp { Op $1 Add $3 }
| Exp '-' Exp { Op $1 Sub $3 }
-- Literals
| num { Num $1 }
| '-' num %prec NEGATIVE { Num (-$2) }
-- Lists
| map Exp Exp { Map $2 $3 }
它产生 4 个减少/减少冲突。删除任何规则也会导致冲突。如果您有兴趣,这里是完整的语法。