我正在尝试在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规则,以及其他一些变体。这里似乎有些事我不明白。非常感激任何的帮助。感谢。
答案 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?也许那里有一些有趣的东西。