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表示输出整个文法树 |