我想解析一个lambda演算。我不知道如何解析术语和尊重括号优先权。例如:
(lx ly (x(xy)))(lx ly xxxy)
我无法找到这样做的好方法。我只是看不到改编的算法。 术语由具有类型(APPLICATION,ABSTRACTION,VARIABLE)的结构表示 “结构术语”类型的左右组件。
知道怎么做吗?
编辑
抱歉再次打扰你,但我真的很想明白。你能检查一下“表达式()”这个函数,让我知道我是不对的。
Term* expression(){
if(current==LINKER){
Term* t = create_node(ABSTRACTION);
get_next_symbol();
t->right = create_node_variable();
get_next_symbol();
t->left = expression();
}
else if(current==OPEN_PARENTHESIS){
application();
get_next_symbol();
if(current != CLOSE_PARENTHESIS){
printf("Error\n");
exit(1);
}
}
else if(current==VARIABLE){
return create_node_variable();
}
else if(current==END_OF_TERM)
{
printf("Error");
exit(1);
}
}
由于
答案 0 :(得分:2)
可以通过将应用程序与其他表达式分开来简化:
EXPR -> l{v} APPL "abstraction"
-> (APPL) "brackets"
-> {v} "variable"
APPL -> EXPR + "application"
与您的方法的唯一区别在于,应用程序表示为表达式列表,因为abcd
可以隐式读取为(((ab)c)d)
,因此您可以将其存储为abcd
解析时。
基于这个语法,可以使用单个前瞻字符创建一个简单的递归下降解析器:
EXPR: 'l' // read character, then APPL, return as abstraction
'(' // read APPL, read ')', return as-is
any // read character, return as variable
eof // fail
APPL: ')' // unread character, return as application
any // read EXPR, append to list, loop
eof // return as application
根符号当然是APPL。作为解析后步骤,您可以将APPL = EXPR列表转换为应用程序树。递归下降非常简单,如果您愿意,您可以轻松地变成具有显式堆栈的命令式解决方案。