0 前言
1 lex & yacc
1.1 Tree Node
typedef struct treeNode{
struct treeNode * child; //儿子
struct treeNode * sibling; //兄弟
int lineno; //行号,仅对terminal有效
NodeKind nodekind; //所有节点类型
char *tokenString; //token的原始值,仅对terminal有效
//blabla后续的自己加属性
}TreeNode;
1.2 Node Kind
| 非终结符 |
终结符 |
| program |
TOKEN_AND |
| program_head |
TOKEN_ARRAY |
| routine |
TOKEN_ASSIGN |
| sub_routine |
TOKEN_BEGIN |
| routine_head |
TOKEN_CASE |
| label_part |
TOKEN_CHAR |
| const_part |
TOKEN_COLON |
| const_expr_list |
TOKEN_COMMA |
| const_value |
TOKEN_CONST |
| type_part |
TOKEN_DIV |
| type_decl_list |
TOKEN_DO |
| type_definition |
TOKEN_DOT |
| type_decl |
TOKEN_DOTDOT |
| simple_type_decl |
TOKEN_DOWNTO |
| array_type_decl |
TOKEN_ELSE |
| record_type_decl |
TOKEN_END |
| field_decl_list |
TOKEN_EQUAL |
| field_decl |
TOKEN_FOR |
| name_list |
TOKEN_FUNCTION |
| var_part |
TOKEN_GE |
| var_decl_list |
TOKEN_GOTO |
| var_decl |
TOKEN_GT |
| routine_part |
TOKEN_ID |
| function_decl |
TOKEN_IF |
| function_head |
TOKEN_INTEGER |
| procedure_decl |
TOKEN_LB |
| procedure_head |
TOKEN_LE |
| parameters |
TOKEN_LP |
| para_decl_list |
TOKEN_LT |
| para_type_list |
TOKEN_MINUS |
| var_para_list |
TOKEN_MOD |
| val_para_list |
TOKEN_MUL |
| routine_body |
TOKEN_NOT |
| compound_stmt |
TOKEN_OF |
| stmt_list |
TOKEN_OR |
| stmt |
TOKEN_PLUS |
| non_label_stmt |
TOKEN_PROCEDURE |
| assign_stmt |
TOKEN_PROGRAM |
| proc_stmt |
TOKEN_RB |
| if_stmt |
TOKEN_READ |
| else_clause |
TOKEN_REAL |
| repeat_stmt |
TOKEN_RECORD |
| while_stmt |
TOKEN_REPEAT |
| for_stmt |
TOKEN_RP |
| direction |
TOKEN_SEMI |
| case_stmt |
TOKEN_STRING |
| case_expr_list |
TOKEN_SYS_CON |
| case_expr |
TOKEN_SYS_FUNCT |
| goto_stmt |
TOKEN_SYS_PROC |
| expression_list |
TOKEN_SYS_TYPE |
| expression |
TOKEN_THEN |
| expr |
TOKEN_TO |
| term |
TOKEN_TYPE |
| factor |
TOKEN_UNEQUAL |
| args_list |
TOKEN_UNTIL |
|
TOKEN_VAR |
|
TOKEN_WHILE |
1.3 全局变量
| 变量 |
含义 |
| int lineno |
记录行号 |
| int traceflag |
是否跟踪输出的开关 |
| int totalLine |
行总数 |
| TreeNode * root |
解析后的根节点 |
| int hasError |
解析中是否遇到过错误 |
1.4 文件说明
| 文件名 |
含义 |
| grammer.txt |
修正后的pascal文法 |
| globals.h |
全局头文件,基本类型(树节点)定义 |
| util.c/util.h |
实用函数模块,比如打印树,打印节点,生成节点 |
| main.c |
编译器主文件 |
| pascal.l |
lex文件 |
| pascal.y |
yacc文件 |
| y.tab.h |
yacc头文件(添加yylval修正) |
1.5 编译指令
yacc pascal.y; lex pascal.l; gcc util.c y.tab.c lex.yy.c main.c -ll ; ./a.out -d < hello.pas
| 文件名 |
含义 |
| yacc pascal.y |
生成yacc的C文件 |
| lex pascal.l |
生成lex的C文件 |
| gcc util.c y.tab.c lex.yy.c main.c -ll |
编译整个工程 |
| ./a.out -d < hello.pas |
加-d表示输出整个文法树 |