Lex和Yacc使用教程(五).再识语法树

Lex和Yacc应用方法(五).再识语法树

草木瓜  20070524

一、序

  在《Lex和Yacc应用教程(四).语法树》一文已对语法树有了初步的概念,本文主要目的
是巩固语法树的概念,并做进一步的扩展分析。闲说少说,首先给出完整示例,本例在Redhat Linux 9
下调试通过,可放心使用。
    另外系列文章的标题,有的叫“lex和yacc应用方法”,有的叫“lex和yacc应用教程”,
还有的叫“lex和yacc使用教程”等等,概念都是一样的。之所以起这么多名字是便于大家通
过搜索引擎能迅速查到。
   
    <本站文章难免有错误疏漏之处。Lex,Yacc系列文章 http://blog.csdn.net/liwei_cmg/category/207528.aspx>

二、示例全代码

本示例包括四个文件
node.h(头文件),lexya_e.l(lex文件),lexya_e.y(yacc文件),parser.c(外部分析文件)

--------------------------------------
A.头文件 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   

 


--------------------------------------
B.lexya_e.l lex文件
  

%{
#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; 

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值