如何解析 lambda 项

发布于 2024-10-07 08:00:17 字数 895 浏览 4 评论 0原文

我想解析 lambda 演算。我不知道如何解析该术语并尊重括号优先级。例如:

(lx ly (x(xy)))(lx ly xxxy)  

我找不到好的方法来做到这一点。我只是看不到适应的算法。 术语由具有类型(应用程序、抽象、变量)的结构表示,并且 “结构术语”类型的左右组件。

知道怎么做吗?

编辑

很抱歉再次打扰您,但我真的很想理解。你能检查一下函数“表达式()”让我知道我是否正确。

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);
    }
} 

谢谢

I would like to parse a lambda calculus. I dont know how to parse the term and respect parenthesis priority. Ex:

(lx ly (x(xy)))(lx ly xxxy)  

I don't manage to find the good way to do this. I just can't see the adapted algorithm.
A term is represented by a structure that have a type (APPLICATION, ABSTRACTION, VARIABLE) and
a right and left component of type "struc term".

Any idea how to do this ?

EDIT

Sorry to disturb you again, but I really want to understand. Can you check the function "expression()" to let me know if I am right.

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);
    }
} 

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

时光匆匆的小流年 2024-10-14 08:00:17

可以通过将应用程序与其他表达式分开来简化:

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 列表转换为应用程序树。递归下降非常简单,如果您愿意,您可以轻松地将其转变为具有显式堆栈的命令式解决方案。

The can be simplified by separating the application from other expressions:

EXPR -> l{v} APPL     "abstraction"
     -> (APPL)        "brackets"
     -> {v}           "variable"

APPL -> EXPR +        "application"

The only difference with your approach is that the application is represented as a list of expressions, because abcd can be implicitly read as (((ab)c)d) so you might at well store it as abcd while parsing.

Based on this grammar, a simple recursive descent parser can be created with a single character of lookahead:

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

The root symbol is APPL, of course. As a post-parsing step, you can turn your APPL = list of EXPR into a tree of applications. The recursive descent is so simple that you can easily turn into an imperative solution with an explicit stack if you wish.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文