Lex Yacc (二) 语法树
2016-05-23 12:18
323 查看
语法树的应用 草木瓜 (四) 源码见百度云盘
详细讲解:草木鱼(四)input
inputi=0; while(i<=10){ print(i); i=i+1; } print(i+i);
node.h
node.h/* 定义树结点的权举类型 */ typedef enum { TYPE_CONTENT, TYPE_INDEX, TYPE_OP } NodeEnum; /* 操作符 */ typedef struct { int name; /* 操作符名称 */ int num; /* 操作元个数 */ struct NodeTag * node[1]; /* 操作元地址 可扩展 */ } OpNode; typedef struct NodeTag { NodeEnum type; /* 树结点类型 */ /* Union 必须是最后一个成员 */ union { int content; /* 内容 */ int index; /* 索引 */ OpNode op; /* 操作符对象 */ }; } Node; extern int Var[26];
lexya_e.l
lexya_e.l%{ #include <stdlib.h> #include "node.h" #include "lexya_e.tab.h" void yyerror(char *); %} %% [a-z] { yylval.sIndex = *yytext - 'a'; return VARIABLE;} [0-9]+ { yylval.iValue = atoi(yytext); return INTEGER;} [()<>=+*/;{}.] { return *yytext;} ">=" return GE; "<=" return LE; "==" return EQ; "!=" return NE; "&&" return AND; "||" return OR; "while" return WHILE; "if" return IF; "else" return ELSE; "print" return PRINT; [\t\n]+ ; /* 去除空格,回车 */ . printf("unknow symbol:[%s]\n", yytext); %% int yywrap(void) { return 1; }
lexya_e.y
lexya_e.y%{ #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include "node.h" /* 属性操作类型 */ Node * opr(int name, int num, ...); //Node *opr(int name, int num, ...); //在内存空间中分配操作符相关的树结点 Node * set_index(int value); //在内存空间分配index的树结点 Node * set_content(int value); void freeNode(Node * p); int exeNode(Node * p); int yylexeNode(void); void yyerror(char *s); int Var[26]; /* 变量数组 */ %} %union { int iValue; /* 变量值 */ char sIndex; /* 变量数组索引 */ Node *nPtr; /* 结点地址 */ }; %token <iValue> VARIABLE %token <sIndex> INTEGER %token WHILE IF PRINT %nonassoc IFX //有关优先级 %nonassoc ELSE %left AND OR GE LE EQ NE '>' '<' %left '+' '-' %left '*' '/' %nonassoc UMINUS %type <nPtr> stmt expr stmt_list %% program: function { exit(0); } ; function: function stmt { exeNode($2); freeNode($2); } | ; stmt: ';' { $$ = opr(';', 2, NULL, NULL); } | expr ';' { $$ = $1; } | PRINT expr ';' { $$ = opr(PRINT, 1, $2); } | VARIABLE '=' expr ';' { $$ = opr('=', 2, set_index($1), $3); } | WHILE '(' expr ')' stmt { $$ = opr(WHILE, 2, $3, $5); } | IF '(' expr ')' stmt %prec IFX { $$ = opr(IF, 2, $3, $5); } | IF '(' expr ')' stmt ELSE stmt %prec ELSE { $$ = opr(IF, 3, $3, $5, $7); } | '{' stmt_list '}' { $$ = $2; } ; stmt_list: stmt { $$ = $1; } | stmt_list stmt { $$ = opr(';', 2, $1, $2); } ; expr: INTEGER {$$ = set_content($1); } | VARIABLE {$$ = set_index($1); } | '-' expr %prec UMINUS {$$ = opr(UMINUS, 1, $2); } | expr '+' expr {$$ = opr('+', 2, $1, $3); } | expr '-' expr { $$ = opr('-', 2, $1, $3); } | expr '*' expr { $$ = opr('*', 2, $1, $3); } | expr '/' expr { $$ = opr('/', 2, $1, $3); } | expr '<' expr { $$ = opr('<', 2, $1, $3); } | expr '>' expr { $$ = opr('>', 2, $1, $3); } | expr GE expr { $$ = opr(GE, 2, $1, $3); } | expr LE expr { $$ = opr(LE, 2, $1, $3); } | expr NE expr { $$ = opr(NE, 2, $1, $3); } | expr EQ expr { $$ = opr(EQ, 2, $1, $3); } | expr AND expr { $$ = opr(AND, 2, $1, $3); } | expr OR expr { $$ = opr(OR, 2, $1, $3); } | '(' expr ')' { $$ = $2; } ; %% #define SIZE_OF_NODE ((char *)&p->content - (char *)p) Node *set_content(int value) { Node *p; size_t sizeNode; /* 分配结点空间 */ sizeNode = SIZE_OF_NODE + sizeof(int); if ((p = malloc(sizeNode)) == NULL) yyerror("out of memory"); /* 复制内容 */ p->type = TYPE_CONTENT; p->content = value; return p; } Node *set_index(int value) { Node *p; size_t sizeNode; /* 分配结点空间 */ sizeNode = SIZE_OF_NODE + sizeof(int); if ((p = malloc(sizeNode)) == NULL) yyerror("out of memory"); /* 复制内容 */ p->type = TYPE_INDEX; p->index = value; return p; } Node *opr(int name, int num, ...) { va_list valist; //声明变量 Node *p; size_t sizeNode; int i; /* 分配结点空间 */ sizeNode = SIZE_OF_NODE + sizeof(OpNode) + (num - 1) * sizeof(Node*); if ((p = malloc(sizeNode)) == NULL) yyerror("out of memory"); /* 复制内容 */ p->type = TYPE_OP; p->op.name = name; p->op.num = num; va_start(valist, num); //开始解析。valist指向num后面的参数。实现变换函数参数的 for (i = 0; i < num; i++) p->op.node[i] = va_arg(valist, Node*); //取下一个参数并返回。valist指向下一个参数 va_end(valist); //结束解析 return p; } void freeNode(Node *p) { int i; if (!p) return; if (p->type == TYPE_OP) { for (i = 0; i < p->op.num; i++) freeNode(p->op.node[i]); } free (p); } void yyerror(char *s) { fprintf(stdout, "%s\n", s); } int main(void) { yyparse(); return 0; }
parser.c
parser.c#include <stdio.h> #include "node.h" #include "lexya_e.tab.h" int exeNode(Node *p) { if (!p) return 0; switch (p->type) { case TYPE_CONTENT: return p->content; case TYPE_INDEX: return Var[p->index]; case TYPE_OP: switch (p->op.name) { case WHILE: while (exeNode(p->op.node[0]))exeNode(p->op.node[1]); return 0; case IF: if (exeNode(p->op.node[0])) exeNode(p->op.node[1]); else if (p->op.num > 2) exeNode(p->op.node[2]); return 0; case PRINT: printf("%d\n", exeNode(p->op.node[0])); return 0; case ';': exeNode(p->op.node[0]); return exeNode(p->op.node[1]); case '=': return Var[p->op.node[0]->index] = exeNode(p->op.node[1]); case UMINUS: return exeNode(p->op.node[0]); case '+': return exeNode(p->op.node[0]) + exeNode(p->op.node[1]); case '-': return exeNode(p->op.node[0]) - exeNode(p->op.node[1]); case '*': return exeNode(p->op.node[0]) * exeNode(p->op.node[1]); case '/': return exeNode(p->op.node[0]) / exeNode(p->op.node[1]); case '<': return exeNode(p->op.node[0]) < exeNode(p->op.node[1]); case '>': return exeNode(p->op.node[0]) > exeNode(p->op.node[1]); case GE: return exeNode(p->op.node[0]) >= exeNode(p->op.node[1]); case LE: return exeNode(p->op.node[0]) <= exeNode(p->op.node[1]); case NE: return exeNode(p->op.node[0]) != exeNode(p->op.node[1]); case EQ: return exeNode(p->op.node[0]) == exeNode(p->op.node[1]); case AND: return exeNode(p->op.node[0]) && exeNode(p->op.node[1]); case OR: return exeNode(p->op.node[0]) || exeNode(p->op.node[1]); } } return 0; }
bison -d lexya_e.y
lex -d lexya_e.l
gcc -g -o parser lex.yy.c lexya_e.tab.c parser.c
./parser < input
再识语法树 草木瓜(五) 源代码有百度云存盘
node.h
node.h/* 定义树结点的权举类型 */ typedef enum { TYPE_CONTENT, TYPE_INDEX, TYPE_OP } NodeEnum; /* 操作符 */ typedef struct { int name; /* 操作符名称 */ int num; /* 操作元个数 */ struct NodeTag * node[1]; /* 操作元地址 可扩展 */ } OpNode; typedef struct NodeTag { NodeEnum type; /* 树结点类型 */ /* Union 必须是最后一个成员 */ union { float content; /* 内容 */ int index; /* 索引 */ OpNode op; /* 操作符对象 */ }; } Node; struct VarIndex { float val; char mark[10]; }; struct VarDefine { int index; char * name; }; #define USER_DEF_NUM 259 /* Yacc编译的保留字开始索引 */ #define MAX_VARS 100 /* 最多变量数 */ #define MAX_DEFS 20 /* 最多保留字数 */ #define MAX_BUFF_COLS 40 /* 分析语句最多行数 */ #define MAX_BUFF_ROWS 40 /* 分析语句每行最多字符数 */ extern struct VarIndex G_Var[MAX_VARS]; /* 存储的变量数组 */ extern struct VarDefine G_Def[MAX_DEFS]; /* 系统保留字变量 */ extern int G_iVarMaxIndex; /* 变量目前总数 */ extern int G_iVarCurIndex; /* 当前操作变量索引 */ extern char G_sBuff[MAX_BUFF_ROWS][MAX_BUFF_COLS]; /* 存储分析语句 */ extern int G_iBuffRowCount; /* 当前语句行数 */ extern int G_iBuffColCount; /* 当前语句列数 */ /* 是否打印调试信息的开关 */ // #define PARSE_DEBUG
lexya_e.l
lexya_e.l%{ #include <stdlib.h> #include "node.h" #include "lexya_e.tab.h" struct VarDefine G_Def[MAX_DEFS]; /* 存储的变量数组 */ char G_sBuff[MAX_BUFF_ROWS][MAX_BUFF_COLS]; /* 存储分析语句 */ int G_iBuffRowCount = 0; /* 当前语句行数 */ int G_iBuffColCount = 0; /* 当前语句列数 */ extern void add_var(char *); /* 在内存中添加变量 */ void add_buff(char *); /* 在内存中添加语句 */ void yyerror(char *); %} /* 使用代变量表示任意字符 */ any . %% #{any}*[\n] { add_buff(yytext); G_iBuffColCount = 0; G_iBuffRowCount++; } /* 单行注释 */ [\n] { G_iBuffColCount = 0; G_iBuffRowCount++; } /* 回车 */ "for" { yylval.index = FOR - USER_DEF_NUM; G_Def[yylval.index].name = "for"; add_buff(yytext); return FOR; } "while" { yylval.index = WHILE - USER_DEF_NUM; G_Def[yylval.index].name = "while"; add_buff(yytext); return WHILE; } "if" { yylval.index = IF - USER_DEF_NUM; G_Def[yylval.index].name = "if"; add_buff(yytext); return IF; } "else" { yylval.index = ELSE - USER_DEF_NUM; G_Def[yylval.index].name = "else"; add_buff(yytext); return ELSE; } "print" { yylval.index = PRINT - USER_DEF_NUM ; G_Def[yylval.index].name = "print"; add_buff(yytext); return PRINT; } [a-zA-Z][a-zA-Z0-9]* { add_var(yytext); yylval.index = G_iVarCurIndex; add_buff(yytext); return VARIABLE; } [0-9]+ { yylval.val = atof(yytext); add_buff(yytext); return NUMBER; } [0-9]*/.[0-9]+ { yylval.val = atof(yytext); add_buff(yytext); return NUMBER; } "++" { yylval.index = ADD_T - USER_DEF_NUM; G_Def[yylval.index].name = "++"; G_Def[yylval.index + 1].name = "++"; add_buff(yytext); return ADD_T; } "--" { yylval.index = MUS_T - USER_DEF_NUM; G_Def[yylval.index].name = "--"; G_Def[yylval.index + 1].name = "++"; add_buff(yytext); return MUS_T; } ">=" { yylval.index = GE - USER_DEF_NUM; G_Def[yylval.index].name = ">="; add_buff(yytext); return GE;} "<=" { yylval.index = LE - USER_DEF_NUM; G_Def[yylval.index].name = "<="; add_buff(yytext); return LE;} "==" { yylval.index = EQ - USER_DEF_NUM; G_Def[yylval.index].name = "=="; add_buff(yytext); return EQ;} "!=" { yylval.index = NE - USER_DEF_NUM; G_Def[yylval.index].name = "!="; add_buff(yytext); return NE;} "&&" { yylval.index = AND - USER_DEF_NUM; G_Def[yylval.index].name = "&&"; add_buff(yytext); return AND;} "||" { yylval.index = OR - USER_DEF_NUM; G_Def[yylval.index].name = "||"; add_buff(yytext); return OR; } [()<>=+/-*/;{}.] { yylval.index = *yytext; /* 存储运算符 */ add_buff(yytext); return *yytext; } [\t] { add_buff(yytext); } /* 去除TAB */ [ ] { add_buff(yytext); } /* 去除空格 */ {any} { printf("Ignore Unknow Symbol:[%s]/n", yytext); } %% void add_buff(char * buff) { strcat(G_sBuff[G_iBuffRowCount], buff); G_iBuffColCount = G_iBuffColCount + strlen(buff); } int yywrap(void) { return 1; }
lexya_e.y
lexya_e.y%{ #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include "node.h" /* 属性操作类型 */ Node * opr(int name, int num, ...); Node * set_index(int value); Node * set_content(float value); /* 树结点操作 */ void NodeFree(Node * p); float NodeExecute(Node * p); typedef union { float val; /* 变量值 */ int index; /* 用于存放 变量数组索引 或 一元操作符值 或 多元操作符索引 */ Node *node; /* 结点地址 */ } yystype; #define YYSTYPE yystype /* 打印分析调试信息 */ void debug_vsp(YYSTYPE , char * , YYSTYPE *, char * ); void print_stmt(); /* 在内存中添加变量 */ void add_var(char *); int G_iVarMaxIndex = 0; /* 变量最大个数 */ int G_iVarCurIndex = -1; /* 变量当前索引 */ struct VarIndex G_Var[MAX_VARS]; /* 变量内存数组 */ void yyerror(char *s); %} %union { float val; /* 变量值 */ int index; /* 变量数组索引 */ Node *node; /* 结点地址 */ }; %token <val> NUMBER %token <index> VARIABLE %token PRINT %token FOR WHILE %nonassoc IF %nonassoc ELSE %left AND OR %left GE LE EQ NE '>' '<' %left '+' '-' %left '*' '/' %left ADD_T ADD_TT MUS_T MUS_TT %nonassoc UMINUS %type <node> stmt stmt_list expr_set expr_setself expr_comp expr %% program: function { exit(0); } ; function: function stmt { NodeExecute($2); NodeFree($2); } | /* NULL */ ; stmt: ';' { $$ = opr(';', 2, NULL, NULL); debug_vsp(yyval, ";", yyvsp, "0"); } | expr_set ';' { $$ = $1; debug_vsp(yyval, "es;", yyvsp, "01"); } | PRINT expr ';' { $$ = opr(PRINT, 1, $2); debug_vsp(yyval, "p(e);", yyvsp, "401"); } | PRINT expr_set ';' { $$ = opr(PRINT, 1, $2); debug_vsp(yyval, "p(es);", yyvsp, "401"); } | FOR '(' expr_set ';' expr_comp ';' expr_set ')' stmt { $$ = opr(FOR, 4, $3, $5, $7, $9); debug_vsp(yyval, "for(es;ec;es) st", yyvsp, "410101010"); } | WHILE '(' expr_comp ')' stmt { $$ = opr(WHILE, 2, $3, $5); debug_vsp(yyval, "while(ec) st", yyvsp, "41010"); } | IF '(' expr_comp ')' stmt %prec IF { $$ = opr(IF, 2, $3, $5); debug_vsp(yyval, "if(ec) st", yyvsp, "41010"); } | IF '(' expr_comp ')' stmt ELSE stmt %prec ELSE { $$ = opr(IF, 3, $3, $5, $7); debug_vsp(yyval, "if(ec)else st", yyvsp, "4101040"); } | '{' stmt_list '}' { $$ = $2; debug_vsp(yyval, "{stl}", yyvsp, "101"); } ; stmt_list: stmt { $$ = $1; debug_vsp(yyval, "st", yyvsp, "0"); } | stmt_list stmt { $$ = opr(';', 2, $1, $2); debug_vsp(yyval, "stl st", yyvsp, "00"); } ; expr_set: VARIABLE '=' expr { $$ = opr('=', 2, set_index($1), $3); debug_vsp(yyval, "v=e", yyvsp, "210"); } | VARIABLE '=' expr_setself { $$ = opr('=', 2, set_index($1), $3); debug_vsp(yyval, "v=ess", yyvsp, "210"); } | expr_setself ; expr_setself: ADD_T VARIABLE { $$ = opr(ADD_T, 1, set_index($2)); debug_vsp(yyval, "++v", yyvsp, "42"); } | MUS_T VARIABLE { $$ = opr(MUS_T, 1, set_index($2)); debug_vsp(yyval, "--v", yyvsp, "42"); } | VARIABLE ADD_T { $$ = opr(ADD_TT, 1, set_index($1)); debug_vsp(yyval, "v++", yyvsp, "24"); } | VARIABLE MUS_T { $$ = opr(MUS_TT, 1, set_index($1)); debug_vsp(yyval, "v--", yyvsp, "24"); } | '(' expr_setself ')' { $$ = $2; debug_vsp(yyval, "(ess)", yyvsp, "101"); } ; expr_comp: expr '<' expr { $$ = opr('<', 2, $1, $3); debug_vsp(yyval, "e<e", yyvsp, "010"); } | expr '>' expr { $$ = opr('>', 2, $1, $3); debug_vsp(yyval, "e>e", yyvsp, "010"); } | expr GE expr { $$ = opr(GE, 2, $1, $3); debug_vsp(yyval, "e>=e", yyvsp, "040"); } | expr LE expr { $$ = opr(LE, 2, $1, $3); debug_vsp(yyval, "e<=e", yyvsp, "040"); } | expr NE expr { $$ = opr(NE, 2, $1, $3); debug_vsp(yyval, "e!=e", yyvsp, "040"); } | expr EQ expr { $$ = opr(EQ, 2, $1, $3); debug_vsp(yyval, "e==e", yyvsp, "040"); } | expr_comp AND expr_comp { $$ = opr(AND, 2, $1, $3); debug_vsp(yyval, "ec&&ec", yyvsp, "040"); } | expr_comp OR expr_comp { $$ = opr(OR, 2, $1, $3); debug_vsp(yyval, "ec||ec", yyvsp, "040"); } | '(' expr_comp ')' { $$ = $2; debug_vsp(yyval, "(ec)", yyvsp, "101"); } ; expr: NUMBER { $$ = set_content($1); debug_vsp(yyval, "f", yyvsp, "3"); } | VARIABLE { $$ = set_index($1); debug_vsp(yyval, "v", yyvsp, "2"); } | '-' NUMBER %prec UMINUS { $$ = set_content(-$2); debug_vsp(yyval, "-e", yyvsp, "13"); } | expr '+' expr { $$ = opr('+', 2, $1, $3); debug_vsp(yyval, "e+e", yyvsp, "010"); } | expr '-' expr { $$ = opr('-', 2, $1, $3); debug_vsp(yyval, "e-e", yyvsp, "010"); } | expr '*' expr { $$ = opr('*', 2, $1, $3); debug_vsp(yyval, "e*e", yyvsp, "010"); } | expr '/' expr { $$ = opr('/', 2, $1, $3); debug_vsp(yyval, "e/e", yyvsp, "010"); } | '(' expr ')' { $$ = $2; debug_vsp(yyval, "(e)", yyvsp, "101"); } ; //| '(' expr error { $$ = $2; printf("ERROR"); exit(0); } %% #define SIZE_OF_NODE ((char *)&p->content - (char *)p) Node *set_content(float value) { Node *p; size_t sizeNode; /* 分配结点空间 */ sizeNode = SIZE_OF_NODE + sizeof(float); if ((p = malloc(sizeNode)) == NULL) yyerror("out of memory"); /* 复制内容 */ p->type = TYPE_CONTENT; p->content = value; return p; } Node *set_index(int value) { Node *p; size_t sizeNode; /* 分配结点空间 */ sizeNode = SIZE_OF_NODE + sizeof(int); if ((p = malloc(sizeNode)) == NULL) yyerror("out of memory"); /* 复制内容 */ p->type = TYPE_INDEX; p->index = value; return p; } Node *opr(int name, int num, ...) { va_list valist; Node *p; size_t sizeNode; int i; /* 分配结点空间 */ sizeNode = SIZE_OF_NODE + sizeof(OpNode) + (num - 1) * sizeof(Node*); if ((p = malloc(sizeNode)) == NULL) yyerror("out of memory"); /* 复制内容 */ p->type = TYPE_OP; p->op.name = name; p->op.num = num; va_start(valist, num); for (i = 0; i < num; i++) p->op.node[i] = va_arg(valist, Node*); va_end(valist); return p; } /**/ void debug_vsp(YYSTYPE yval, char * info, YYSTYPE * vsp, char * mark) { #ifdef PARSE_DEBUG printf("/n -RULE 0x%x %s /n ", yval.node, info ); int i; int ilen = strlen(mark); for (i = 1 - ilen; i <= 0; i++) { switch (mark[ilen + i - 1]) { case '0': printf(" [ 0x%x ", vsp[i].node); //「」 switch (vsp[i].node->type) { case TYPE_CONTENT: printf("%g ] ", vsp[i].node->content); break; case TYPE_INDEX: printf("%s ] ", G_Var[vsp[i].node->index].mark); break; case TYPE_OP: if (vsp[i].node->op.name < USER_DEF_NUM) printf("%c ] ", vsp[i].node->op.name); else printf("%s ] ", G_Def[vsp[i].node->op.name - USER_DEF_NUM].name); break; } break; case '1': printf(" %c ", vsp[i].index); /* 打印运算符 */ break; case '2': printf(" %s ", G_Var[vsp[i].index].mark); break; case '3': printf(" %g ", vsp[i].val); break; case '4': printf(" %s ", G_Def[vsp[i].index].name); break; } } printf("/n"); print_stmt(); #endif } void add_var(char *mark) { if (G_iVarMaxIndex == 0) { strcpy(G_Var[0].mark, mark); G_iVarMaxIndex++; G_iVarCurIndex = 0; return; } int i; for (i = 0; i <= G_iVarMaxIndex - 1; i++) { if (strcmp(G_Var[i].mark, mark) == 0) { G_iVarCurIndex = i; return; } } strcpy(G_Var[G_iVarMaxIndex].mark, mark); G_iVarCurIndex = G_iVarMaxIndex; G_iVarMaxIndex++; } void print_stmt() { printf(" -STMT: /n"); /* int i; for(i=0;i<=G_iBuffRowCount;i++) printf("%s /n",G_sBuff[i]); */ if (G_iBuffColCount == 0) printf(" %s /n", G_sBuff[G_iBuffRowCount - 1]); else printf(" %s /n", G_sBuff[G_iBuffRowCount]); printf("/n"); } void NodeFree(Node *p) { int i; if (!p) return; if (p->type == TYPE_OP) { for (i = 0; i < p->op.num; i++) NodeFree(p->op.node[i]); } free (p); } void yyerror(char *s) { //fprintf(stdout, "%s/n", s); printf("<Parser Error> Line %d ,Col %d /n", G_iBuffRowCount + 1, G_iBuffColCount + 1); printf(" %s/n", G_sBuff[G_iBuffRowCount]); } int main(void) { yyparse(); return 0; }
parser.c
parser.c#include <stdio.h> #include "node.h" #include "lexya_e.tab.h" float NodeExecute(Node *p) { if (!p) return 0; switch (p->type) { case TYPE_CONTENT: return p->content; case TYPE_INDEX: return G_Var[p->index].val; case TYPE_OP: switch (p->op.name) { case WHILE: while (NodeExecute(p->op.node[0]))NodeExecute(p->op.node[1]); return 0; case FOR: NodeExecute(p->op.node[0]); while (NodeExecute(p->op.node[1])) { NodeExecute(p->op.node[3]); NodeExecute(p->op.node[2]); } return 0; case IF: if (NodeExecute(p->op.node[0])) NodeExecute(p->op.node[1]); else if (p->op.num > 2) NodeExecute(p->op.node[2]); return 0; case PRINT: printf("%g\n", NodeExecute(p->op.node[0])); return 0; case ';': NodeExecute(p->op.node[0]); return NodeExecute(p->op.node[1]); case '=': return G_Var[p->op.node[0]->index].val = NodeExecute(p->op.node[1]); case UMINUS: return NodeExecute(p->op.node[0]); case '+': return NodeExecute(p->op.node[0]) + NodeExecute(p->op.node[1]); case '-': return NodeExecute(p->op.node[0]) - NodeExecute(p->op.node[1]); case '*': return NodeExecute(p->op.node[0]) * NodeExecute(p->op.node[1]); case '/': return NodeExecute(p->op.node[0]) / NodeExecute(p->op.node[1]); case '<': return NodeExecute(p->op.node[0]) < NodeExecute(p->op.node[1]); case '>': return NodeExecute(p->op.node[0]) > NodeExecute(p->op.node[1]); case GE: return NodeExecute(p->op.node[0]) >= NodeExecute(p->op.node[1]); case LE: return NodeExecute(p->op.node[0]) <= NodeExecute(p->op.node[1]); case NE: return NodeExecute(p->op.node[0]) != NodeExecute(p->op.node[1]); case EQ: return NodeExecute(p->op.node[0]) == NodeExecute(p->op.node[1]); case AND: return NodeExecute(p->op.node[0]) && NodeExecute(p->op.node[1]); case OR: return NodeExecute(p->op.node[0]) || NodeExecute(p->op.node[1]); case ADD_T: return ++G_Var[p->op.node[0]->index].val; case MUS_T: return --G_Var[p->op.node[0]->index].val; case ADD_TT: return G_Var[p->op.node[0]->index].val++; case MUS_TT: return G_Var[p->op.node[0]->index].val--; } } return 0; }
input
inputk=9; if((1>1)||(-9>-1)) for(i=0;i<=9;i=i+1) print(i); else if(3>1&&2>1) { for(j=-1.1;j<=3;j++) print(j); for(jdd=1;jdd<=3;++jdd) print(jdd); while(k<=9) { print(k++); print(++k); } } #test
功能介绍
bison -d lexya_e.ylex -d lexya_e.l
gcc -g -o parser lex.yy.c lexya_e.tab.c parser.c
./parser < input
以上示例显然是根据《Lex和Yacc应用教程(四).语法树》文中的示例扩展而来。主要演示C语言类似的语法编译方法。支持的功能如下:
1. 支持整型和浮点型 2. 支持变量存储,变量名可为多个字符 3. 支持+-*/()=运算法则 4. 支持负数及负数运算 5. 支持变量的自加(++)和自减运算(--),区分前自加减和后自加减 6. 支持print打印值和变量 7. 支持for while if else控制结构,并支持控制结构的嵌套 8. 支持>= <= != ==四种比较运算 9. 支持&& ||的复合比较运算 10. 支持对空格和TAB的忽略处理 11. 支持#的单行注释 12. 支持{}多重组合 13. 支持编译错误的具体显示 14. 支持编译过程的变量堆栈信息打印,便于调试分析 15. 支持保留字的存储显示。 16. 支持语法树打印(将在下一篇文章着重说明)
相关文章推荐
- 项目4-日期时间类
- 陶哲轩实分析-第8章-无限集合
- 二分图最大匹配各种题型
- PHP中header用法小结
- 【bzoj4380】[POI2015]Myjnie
- 持续部署单页应用的7大技巧
- 陶哲轩实分析-第5章-实数
- [HDU 4418] Time travel
- 浅谈设计模式之建造者模式
- 通过ODBC 创建Oracle 的DBlink
- Jackson - Quickstart
- UITableViewCell - accessoryType属性
- 第十三周阅读程序-交通工具类(1)
- JAVA面向对象变成学习!
- Java设计模式(二):单例模式的5种实现方式,以及在多线程环境下5种创建单例模式的效率
- 解决linux kernerl3.13 安装vmware10 vnet错误
- Spark Checkpoint写操作代码分析
- IOS 正则表达式(NSPredicate的使用)
- 课程练习三-1015-problem O
- TensorFlow教程06:MNIST的CNN实现——源码和运行结果