我们现在开始设计数据结构:
- interpreter.h
- #ifndef INTERPRETER
- #define INTERPRETER
- #include "../include/eval.h"
- typedef struct interpreter_tag Interpreter;
- struct interpreter_tag
- {
- MEM_Storage storage;// 存储器
- MEM_Storage charpool;
- Statement_list *list;// 语句表
- Function_t *functionlist;// 函数表
- Environment globalEnvironment;// 全局变量存放的位置
- };
- Interpreter *getInterpreterInstance();
- void *Interpreter_malloc(int size);// 使用存储器分配内存
- char *Interpreter_str_malloc(char *str);// 分配字符串
- #endif
Interpreter 就是解释器的结构体, 存放一些全局信息, 在需要的时候可以通过 getInstance 获取实例
我们的解释器执行的时候是先使用 yylex 构建抽象语法树 (AST), 然后再解释执行
我们先来看一下语句的结构体:
- struct Statement_tag
- {
- enum StatementType type;
- union {
- ExpressionStatement *e;// 表达式语句
- For_Statement *f;//for 语句
- If_Statement *i;//if 语句
- } u;
- };
我们把表达式语句, if 和 for 语句放在一个联合体中, 通过 type 来区分不同的联合体, 比直接使用 void * 更方便
表达式语句中存放一个表达式
- struct Expression_Statement_tag
- {
- Expression *expression;
- };
表达式也和语句一样, 使用 type 来区分指针
- struct Expression_tag
- {
- enum Expression_type type;
- Expression_u u;
- };
- union Expression_uni {
- PrimaryExpression *p;// 这个主要跟文法中 primary_expresison 对应
- Binary_Expression *b;// 主要跟二元操作对应, 比如 add sub mul div eq ne
- Assign_Expression *a;// 赋值表达式
- Expression *e;// 表达式指针
- FuncCallExpression *func;// 函数表达式
- };
我们先来看 primaryexpression 结构体, 里面同理里使用枚举来确定联合体里面保存的变量类型
- struct PrimaryExpression_tag
- {
- enum ValueType type;
- union {
- int i;
- double d;
- // char *str;
- MString*mstring;
- char *identifier;
- } u;
- };
注意其中 mstring 是由引用计数管理的字符串指针
- Expression *create_IntergerExpression(int i);// 创建一个整数表达式
- Expression *create_DoubleExpression(double i);// 创建一个浮点数表达式
- Expression *create_StrExpression(char *p);// 创建一个字符串表达式
- Expression *create_IDExpression(char *p);// 创建一个 identitier 表达式
- Binary_Expression *createBinaryExpression(enum ExpressionAction action, Expression *left, Expression *right);// 二元表达式
- Assign_Expression *createAssignExpression(char *c, Expression *expression);// 赋值表达式
- Expression *binExpressionWarpper(Binary_Expression *expression);// 二元表达式包装为 Expression
- Expression *AssignExpressionWarpper(Assign_Expression *expression);// 赋值
- Expression *create_FuncCallExpression(char *identifier, ParamList *params);// 创建函数
这些函数是各个表达式创建函数我们可以在 bison 语法文件 m.y 中使用这些函数
这里拿 primaryexpression 举例
- primary_expression:SUB primary_expression
- {
- $$=$2;
- }
- |LP expression RP
- {
- $$=$2;
- }
- |IDENTIFIER
- {
- $$=create_IDExpression($1);
- }
- |STRING_LITERAL
- {
- $$=create_StrExpression($1);
- }
- |INT_LITERAL
- {
- $$=create_IntergerExpression($1);
- }
- |DOUBLE_LITERAL
- {
- $$=create_DoubleExpression($1);
- }
- |IDENTIFIER LP RP
- {
- $$=create_FuncCallExpression($1,NULL);
- }
- |IDENTIFIER LP arglist RP
- {
- $$=create_FuncCallExpression($1,$3);
- }
- ;
$$ 代表是将会压入栈中的变量,$n 是代表当前参与规约的第 n 个元素, 比如 IDENTIFIER LP arglist RP 中 $1 代表 IDENTIFIER,$3 代表 arglist
当使执行规约的时候会自动执行 action{}, 最后形成抽象语法树把各个表达式连接起来
代码已经上传至 GitHub 地址: https://github.com/stdpain/compiler-interpreter
可以看一下 create.c 和 ms.y
来源: http://www.bubuko.com/infodetail-2986796.html