Abstract syntax tree 莱克斯&;编译作业

Abstract syntax tree 莱克斯&;编译作业,abstract-syntax-tree,yacc,lex,Abstract Syntax Tree,Yacc,Lex,您好(我的英语不是很好,希望您能理解),我有一个misson要做一个编译器,已经用lex和yacc做了语言,但是我很困,我们的老师要求我们用语言构建AST树并按预定顺序打印。他给我们举了一个例子: function void foo(int x, y, z; real f) { if (x>y) { x = x + f; } else { y = x + y + z; x = f * 2; z =

您好(我的英语不是很好,希望您能理解),我有一个misson要做一个编译器,已经用lex和yacc做了语言,但是我很困,我们的老师要求我们用语言构建AST树并按预定顺序打印。他给我们举了一个例子:

function void foo(int x, y, z; real f) {
     if (x>y) {
        x = x + f;
     }
     else {
        y = x + y + z;
        x = f * 2;
        z = f;
     }
}
带预排序的AST树的输出应为:

(CODE
     (FUNCTION
     foo
     (ARGS
          (INT x y z)
          (REAL f)
     )
     (TYPE VOID)
     (BODY 
          (IF-ELSE
          (> x y)
          (BLOCK
                (= x 
                     (+ x f)
                )
           )
          (BLOCK
                (= y
                     (+
                         (+ x y) 
                         z
                     )
                )
                (
                     (= x
                         (* f 2)

                     )
                     (= z f)
                )
          )
    )
)
我的问题是我应该如何建造这棵树?我的意思是哪个令牌将向左,哪个令牌将向右,这样我就可以得到相同的输出? 像

makeTree(1美元、2美元、3美元)


请帮忙:)

斯蒂芬·约翰逊大约在42年前写了一篇技术论文陪伴雅克。你读过了吗?你明白了吗

如果是,语法规则如下:

expr   :   expr '+' expr      { $$ = node( '+', $1, $3 ); } 
节点有效地创建抽象语法树节点;yacc执行的每个缩减都是从下至上构建此树的机会。这是了解yacc最重要的事情;它是自下而上构建的,您需要同样地构建数据结构

当解析完成时(对于complete语法生成的任何版本),结果值($$)就是语法树的根

后续行动 您可能需要设计一个节点数据结构,如下所示:

typedef struct Node Node;
typedef struct NodeList NodeList;
struct NodeList {
     int Num;
     Node *List;
};
struct Node {
      int Type;
      union {
          unsigned u; unsigned long ul; char *s, ... ;
          Variable *var;
          Node *Expression;
          NodeList *List;
      } Operands[3];
};
这样,您就可以设计一个“+”类型的节点,它定义了两个操作数,分别对应于“+”操作码的左侧和右侧。 您还可以有IF类型的节点,该节点有三个操作数:

  • 条件表达式
  • 如果条件为true,则要执行的节点列表
  • 如果条件为false,则要执行的节点列表
  • 可以有一个Func类型的节点,该节点有三个操作数:

  • 返回值的一种类型
  • 一系列论据
  • 构成函数体的节点列表

  • 我会给出更多的例子,但是用这个用户界面格式化列表就像把鲸鱼踢下海滩一样有趣。

    斯蒂芬·约翰逊在42年前写了一篇技术论文陪伴yacc。你读过了吗?你明白了吗

    如果是,语法规则如下:

    expr   :   expr '+' expr      { $$ = node( '+', $1, $3 ); } 
    
    节点有效地创建抽象语法树节点;yacc执行的每个缩减都是从下至上构建此树的机会。这是了解yacc最重要的事情;它是自下而上构建的,您需要同样地构建数据结构

    当解析完成时(对于complete语法生成的任何版本),结果值($$)就是语法树的根

    后续行动 您可能需要设计一个节点数据结构,如下所示:

    typedef struct Node Node;
    typedef struct NodeList NodeList;
    struct NodeList {
         int Num;
         Node *List;
    };
    struct Node {
          int Type;
          union {
              unsigned u; unsigned long ul; char *s, ... ;
              Variable *var;
              Node *Expression;
              NodeList *List;
          } Operands[3];
    };
    
    这样,您就可以设计一个“+”类型的节点,它定义了两个操作数,分别对应于“+”操作码的左侧和右侧。 您还可以有IF类型的节点,该节点有三个操作数:

  • 条件表达式
  • 如果条件为true,则要执行的节点列表
  • 如果条件为false,则要执行的节点列表
  • 可以有一个Func类型的节点,该节点有三个操作数:

  • 返回值的一种类型
  • 一系列论据
  • 构成函数体的节点列表

  • 我会给出更多的例子,但使用此UI格式化列表与将鲸鱼踢下海滩一样有趣。

    请描述您迄今为止为解决此问题所做的工作。搜索了整个互联网,尝试使用此示例再次构建树,但未成功,已经有4天尝试配置了,请描述您到目前为止为解决此问题所做的工作。搜索了整个internet,尝试用此示例重新构建树,但没有成功,已经有4天尝试配置了,但例如,如果我获得令牌“FUNCTION”、“VOID”、“FOO”,我应该将VOID放在哪里,FOO放在哪里?右或左这是我不理解的,但例如,如果我得到标记'FUNCTION','VOID','FOO',我应该把VOID放在哪里,FOO放在哪里?这是我不明白的