Lex Yacc (二) 语法树

来源:互联网 发布:做淘宝去哪里找货源 编辑:程序博客网 时间:2024/05/18 15:04

语法树的应用 草木瓜 (四) 源码见百度云盘

  • 详细讲解:草木鱼(四)

input

  • input
i=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

  • input
k=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.y
  • lex -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. 支持语法树打印(将在下一篇文章着重说明)
0 0
原创粉丝点击