在Rascal中解析并实现lambda演算

时间:2015-01-14 18:32:13

标签: parsing lambda lambda-calculus rascal

我正在尝试在Rascal中实现lambda演算,但是我很难获得优先级并且解析以我希望的方式工作。目前我的语法看起来像:

keyword Keywords= "if" | "then" | "else"  | "end" | "fun";

lexical Ident = [a-zA-Z] !>> [a-zA-Z]+ !>> [a-zA-Z0-9] \ Keywords;
lexical Natural = [0-9]+  !>> [0-9];
lexical LAYOUT = [\t-\n\r\ ];
layout LAYOUTLIST = LAYOUT*  !>> [\t-\n\r\ ];

start syntax Prog = prog: Exp LAYOUTLIST;

syntax Exp =
    var: Ident
    | nat: Natural
    | bracket "(" Exp ")"
    > left app: Exp Exp
    > right func: "fun" Ident "-\>" Exp

当我解析表单的程序时:

(fun x -> fun y -> x) 1 2

结果树是:

prog(app(
    app(
      func(
        "x",
        func(
          "y",
          var("x")
      nat(1),
    nat(2))))))

我真的想找到这样的东西(我想):

prog(app(
    func(
      "x",
      app(
        func(
          "y",
          var("x")),
        nat(2))),
    nat(1)))

我在语法中尝试了许多优先级的变体,我尝试在括号中包装App规则,以及其他一些变体。这里似乎有些事我不明白。非常感激任何的帮助。感谢。

1 个答案:

答案 0 :(得分:1)

我使用了以下语法,删除了额外的LAYOUTLIST和死的right,但这不应该有所作为。当我使用通用implode函数时,它似乎可以正常工作:

keyword Keywords= "if" | "then" | "else"  | "end" | "fun";

lexical Ident = [a-zA-Z] !>> [a-zA-Z]+ !>> [a-zA-Z0-9] \ Keywords;
lexical Natural = [0-9]+  !>> [0-9];
lexical LAYOUT = [\t-\n\r\ ];
layout LAYOUTLIST = LAYOUT*  !>> [\t-\n\r\ ];

start syntax Prog = prog: Exp;

syntax Exp =
    var: Ident
    | nat: Natural
    | bracket "(" Exp ")"
    > left app: Exp Exp
    > func: "fun" Ident "-\>" Exp
    ;

然后调用解析器并插入到无类型的AST(为了便于阅读,我删除了位置注释):

rascal>import ParseTree;
ok
rascal>implode(#node, parse(#start[Prog], "(fun x -\> fun y -\> x) 1 2"))
node: "prog"("app"(
        "app"(
          "func"(
            "x",
            "func"(
              "y",
              "var"("x"))),
          "nat"("1")),
        "nat"("2")))

所以,我猜你得到了你想要的树形状的语法。你如何从具体的解析树到抽象的AST?也许那里有一些有趣的东西。