适用于lambda演算的Python解析器

时间:2019-04-10 16:24:36

标签: python parsing lambda-calculus peg

为了娱乐,我想为未类型化的Lambda演算编写一个解析器。的 最简单的方法可能是编写手写解析器,但是我想知道 如果还有更Python化的方式?具体来说,我想使用 转换语言语法描述的Python库 解析器。这是该语言的BNF定义:

<term> ::= <var>
        |  <term> <term>
        |  λ <var> <term>

为简单起见,我省略了括号规则。应用助理 到左侧,这样x y z(x y) z

哪个Python库可以采用上述语法描述,或某些 从中衍生出的文法(如我所写,文法是 模棱两可且左递归,因此实现起来并非易事),并且 产生解析器?我想看看它是如何使用代码完成的,所以请 不要仅仅回答“小偷就能做到”。请沿着 以下行:

>>> G = """syntax description here..."""
>>> parser = build.the_parser(G)
>>> parser.parse("λ x. (y z)")
Abs('x', App(Id('x', Id('y'))))

最后一行是所产生的抽象语法树的内容。腹肌 代表抽象(lambda),代表应用程序,代表ID 标识符。我认为PEG packrat解析器生成器在这里可以很好地工作。

2 个答案:

答案 0 :(得分:1)

这个ANTLR4语法可以达到目的:

grammar T;

program
 : term EOF
 ;

term
 : Lambda Id '.' term
 | '(' term ')'
 | term term
 | Id
 ;

Lambda
 : '\u03BB'
 ;

Id
 : [a-z] [a-zA-Z0-9]*
 ;

Spaces
 : [ \t\r\n] -> skip
 ;

将以上内容放置在名为T.g4的文件中。将ANTLR4 jar下载到同一文件夹中并执行以下操作:

java -cp antlr-4.7.2-complete.jar org.antlr.v4.Tool -Dlanguage=Python3 T.g4

这将创建词法分析器和解析器文件。

现在运行:

from antlr4 import *
from playground.TLexer import TLexer
from playground.TParser import TParser


tests = [
  'λ x. (y z)', 
  'x y z w'
]

for test in tests:
    lexer = TLexer(InputStream(test))
    parser = TParser(CommonTokenStream(lexer))
    tree = parser.program()
    print("{}".format(tree.toStringTree(recog=parser)))

将打印:

(program (term λ x . (term ( (term (term y) (term z)) ))) <EOF>)
(program (term (term (term (term x) (term y)) (term z)) (term w)) <EOF>)

答案 1 :(得分:0)

这里是删除左递归的替代方法。尽管访问语法树是OP的一种练习。

.2.

.3.
.4.