我正在研究为夏季项目编写语言和编译器,并且很难找到有关如何使用解析树或BNF / EBNF来编写编译器的信息。总体目标是编写一个将简化的函数式语言语法解析为c的编译器。我目前正计划用c语言编写这个编译器,但如果有人认为这是一个更好的主意,我不介意在别的东西上做。 (我确实想用手工做,不使用像LEX这样的工具)
例如,如果我想创建语言ADD
并将其语法定义为(+ 3 4)
,则很容易为其生成EBNF:
Program -> {Function}
Function -> Operator Integer Integer
Operator -> +
Integer -> Digit {Digit}
Digit -> 0|1|2|3|4|5|6|7|8|9
并且更容易制作解析树:
Function
|
-------------------
| | |
Operator Integer Integer
但你怎么样:
我觉得如果我能看到一个非常简单的工作示例,那就足以让我开始朝着正确的方向前进。我有一种感觉,你们很多人会建议我阅读Dragon Book
(似乎是编译器的标准资源),所以我想告诉你它已经订购并发货了。
提前感谢您可以获得的任何亮光!
-vikingsheepman
答案 0 :(得分:1)
从龙书中,一种表示EBNF的方法是使用枚举来对节点的类型进行分组。例如:
typedef enum { StmtK , ExpK} NodeKind;
typedef enum { IfK, AssignK, ... } StmtKind;
typedef enum { OpK, ConstK} ExpKind;
typedef enum { Void, Integer } ExpType;
以这种方式定义树的节点
typedef struct treeNode {
struct treeNode * child[MAXCHILDREN];
struct treeNode * sibling;
int lineNo;
NodeKind nodekind;
union { StmtKind stmt; ExpKind exp; } kind; //Use union to save space
union { TokenType op;
int val;
char * name; } attr;
ExpType type; //To verify expression types
} TreeNode;
生成C代码还有很长的路要走,但实质上你需要对生成的树(语法,语义......)进行一些检查,然后生成代码。怎么做取决于你正在构建的编译器的类型(一个或多个传递)。如果您订购了龙书,肯定会在那里找到所有这些。