符号表

列举单词表的方式虽然简单但是不全面,如果在词法分析程序运行时可以构建一个单词表,那么就可以在添加新的单词时不用修改词法分析程序。

下面示例便利用符号表实现,即在词法分析程序运行时从输入文件中读取声明的单词时允许动态的声明单词。声明以词性的名字开始,后面跟着要声明的单词。

添加符号表可以完全的改变词法分析程序,不必在词法分析程为每个要匹配的单词放置独立的模式,只要有一个匹配任意单词的模式,再查阅符号表就能决定所找到的词性。

lex程序ch1-04.l

%{
/*
*带符号表的词法分析程序
*/ enum{
LOOKUP = 0, /*默认——查找而不是定义*/
VERB,
ADJ,
ADV,
NOUN,
PREP,
PRON,
CONJ
}; int state;
int add_word(int type, char *word);
int lookup_word(char *word);
%} %%
\n {state = LOOKUP;} /*行结束,返回到默认状态*/ /*无论何时,行都以保留字的词性名字开始*/
/*定义该类型的单词*/
^verb {state = VERB;}
^adj {state = ADJ;}
^adv {state = ADV;}
^noun {state = NOUN;}
^prep {state = PREP;}
^pron {state = PRON;}
^conj {state = CONJ;} [a-zA-Z]+ {
/*一个标准的单词、定义或者查找它*/
if(state != LOOKUP){
/*定义当前单词*/
add_word(state,yytext);
}else{
switch(lookup_word(yytext)){
case VERB: printf("%s: verb\n",yytext); break;
case ADJ: printf("%s: adj\n",yytext); break;
case ADV: printf("%s: adv\n",yytext); break;
case NOUN: printf("%s: noun\n",yytext); break;
case PREP: printf("%s: prep\n",yytext); break;
case PRON: printf("%s: pron\n",yytext); break;
case CONJ: printf("%s: conj\n",yytext); break;
default:
printf("%s: don't recognize\n",yytext);
break;
}//switch
}//else
}
/*忽略其他的东西*/
%% int main()
{
yylex();
} /*定义一个连接的单词和类型列表*/
struct word{
char *word_name;
int word_type;
struct word *next;
}; struct word *word_list; //first element in word list extern void *malloc(); int add_word(int type, char *word)
{
struct word *wp;
if(lookup_word(word) != LOOKUP)
{
printf("!!! warning : word %s already defined \n ",word);
return 0;
}//if /*单词不在那里,分配一个新的条目并将它连接到列表上*/
wp = (struct word*) malloc (sizeof(struct word)); wp->next = word_list; /*还必须复制单词本身*/
wp->word_name = (char *)malloc(strlen(word)+1);
strcpy(wp->word_name,word);
wp->word_type = type;
word_list = wp;
return 1; /*它被处理过*/
} int lookup_word(char *word)
{
struct word *wp = word_list; /*向下搜索列表以寻找单词*/
for(; wp ; wp = wp->next)
{
if(strcmp(wp->word_name , word) == 0)
return wp->word_type;
}//for
return LOOKUP;
} int yywrap()
{
return 1;
}

运行命令及结果:

程序代码说明:

在上述lex词法分析程序中,add_word()表示在符号表中放置一个新的单词;

lookup_word()表示查询已经输入的单词。

在程序代码中,声明一个变量state,用来记录是在查找单词(状态LOOKUP)还是在声明它们(在这种情况下,state能记住我们正在声明的单词种类)。

无论何时,只要我们看到以词性名字开始的行,就可以将状态设置为声明单词的种类;每次看到\n时就都切换回正常的查找状态。

Lex与Yacc学习(三)之符号表的更多相关文章

  1. Lex与Yacc学习(一)之环境配置篇

    Abstract 在开发程序的过程中经常会遇到文本解析的问题,例如:解析 C 语言源程序,编写 脚本引擎等等,解决这种文本解析的方法有很多,一种方法就是自己手动用 C 或者 C++直接编写解析程序,这 ...

  2. Lex与Yacc学习(九)之Yacc语法

    Yacc语法 本文讨论yacc语法的格式并描述可用的各种特征和选项 yacc语法结构 yacc语法包括三部分:定义段.规则段和用户子例程段 ...定义段... %% ...规则段... %% ...用 ...

  3. Lex与Yacc学习(四)之Lex规范

    Lex规范的结构 lex程序由三部分组成:定义段.规则段和用户子例程序段 ...定义段... %% ...规则段... %% ...用户子例程序段... 这些部分由以两个百分号组成的行分隔开.尽管某一 ...

  4. Lex与Yacc学习(十)之Yacc库

    Yacc库 每个实现都需要有用的例程库,在UNIX系统中,可以通过cc命令行尾端给出-ly标志(或通过其他系统下的等价物)来包含库. 库的内容在不同的实现之间是不同的,但总是包括main()和yyer ...

  5. Lex与Yacc学习(六)之lex & yacc (简单计算器程序) 运行

    词法分析程序ch3-01.l %{ #include "ch3-01.tab.h" extern int yylval; %} %% [0-9]+ { yylval = atoi( ...

  6. Lex与Yacc学习(五)之正则表达式篇

    正则表达式语法 lex模式是由编辑程序和实用程序使用的正则表达式的扩展版本.正则表达式由常规字符(代表它们本身)和元字符(在一种模式中具有特殊含义)组成. 元字符 . . 匹配除了换行符 \n 之外的 ...

  7. Hibernate学习(三)自动建表

    一般情况下有如下两种方法: 1.在配置文件中添加如下配置 <property name="hibernate.hbm2ddl.auto">create</prop ...

  8. Lex与Yacc学习(二)之第一个Lex程序

    用lex识别单词 构建一个识别不同类型英语单词的简单程序.先识别词性(名词,动词等),然后再扩展到处理符合简单英语语法的多个单词的句子. 先列出要识别的一组动词: is    am   are   w ...

  9. Lex与Yacc学习

    http://www.cnblogs.com/shine-yr/p/5214976.html

随机推荐

  1. scrapy框架中Item Pipeline用法

    scrapy框架中item pipeline用法 当Item 在Spider中被收集之后,就会被传递到Item Pipeline中进行处理 每个item pipeline组件是实现了简单的方法的pyt ...

  2. python 基础(三) 程序基本流程

    流程控制 流程结构分为3种 顺序结构 分支结构 循环结构 一  分支结构 (1) 单一条件分支 主体结构: if 条件表达式:   #为真得代码块   (2) 双向条件分支 主体结构: if 条件表达 ...

  3. Codeforces 1142C(转化、凸包)

    可以变换坐标:x' = x, y' = y - x ^ 2,如此之后可得线性函数x' * b + c = y',可以发现两点连边为抛物线,而其他点都在这条线下方才满足题意,故而求一个上凸壳即可. #i ...

  4. 085 Maximal Rectangle 最大矩形

    给定一个填充了 0 和 1 的二进制矩阵,找到最大的只包含 1 的矩形并返回其面积.例如,给出以下矩阵:1 0 1 0 01 0 1 1 11 1 1 1 11 0 0 1 0返回 6 详见:http ...

  5. Azkaban是什么?(一)

    不多说,直接上干货! http://www.cnblogs.com/zlslch/category/938837.html Azkaban是什么?  Azkaban是一套简单的任务调度服务,整体包括三 ...

  6. CI模板中如何引入模板

    <?php $this->load->view('index/head.html') ?>

  7. GIT GUI克隆github代码

    新建一个文件夹,右击gitgui  git clone 去掉不要

  8. table表格字母无法换行

    在项目中,用到的table比较多,本来布局挺好的,后来在td内写入英文字母,整个布局就乱了,会撑的很宽,不换行,后来才知道:一般字母的话会被浏览器默认是一个字符串或者说一个单词,所以不会自动换行. 于 ...

  9. ReactiveCocoa 响应式函数编程

    简介 ReactiveCocoa(简称为RAC),RAC具有函数响应式编程特性,由Matt Diephouse开源的一个应用于iOS和OS X的新框架. 为什么使用RAC? 因为RAC具有高聚合低耦合 ...

  10. 项目在cocos 2.23移植到cocos 3.1.0所出现的bug

    在建项目时一定要注意选择源代码!而不是预编译库 "extensions/ExtensionMacros.h”: No such file 项目右键-属性-配置属性-c/c++ - 常规-附加 ...