符号表

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

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

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

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. JavaScript引擎基本原理:Shapes和Inline Caches

    原文链接: JavaScript engine fundamentals:Shapes and line Cahes 这篇文章描述了一些在js引擎中通用的关键点, 并不只是V8, 这个引擎的作者(Be ...

  2. qq登录,新浪微博登录接口申请过程中遇到的问题

    接口申请下来了,开发很容易的,参数传到就可以了.以前就做过这方面的开发,但是申请还是第一次,网上有关这方面的东东不是很多,所以记录一下申请过程. 1,qq登录接口申请 申请地址是:http://con ...

  3. JS核心

    JS核心 1.实例化对象 objectName = new objectType (param1 [,param2] ...[,paramN]) 参数  objectName 新对象实例的名称. ob ...

  4. 自定义消息中如果需要定义WPARAM和LPARAM,该怎么使用和分配?

    写Windows程序不可避免要使用自定义的消息,也就是从WM_USER开始定义的消息.在定义一个消息后,往往我们还要定义针对该消息的WPARAM甚至是LPARAM.WPARAM和LPARAM是什么,可 ...

  5. Lucene全文检索技术学习

    ---------------------------------------------------------------------------------------------------- ...

  6. https增加临时证书,tomcat配置

    1Windows下: 1.1 生成keystore文件及导出证书 打开控制台: 运行: %JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RS ...

  7. mac ssd开启trim模式

    开启方法 sudo trimforce enable

  8. 11gR2新特性---Gpnp守护进程

    在这篇文章中,我们会对11gR2 新的守护进程(资源名称ora.gpnpd)进行介绍,其中包含的gpnp的功能,启动顺序和基本的诊断方法. gpnp全称为grid plug and play,该组件的 ...

  9. 机器学习之 PCA

    PCA(Principal Component Analysis)是一种常用的数据分析方法.PCA通过线性变换将原始数据变换为一组各维度线性无关的表示,可用于提取数据的主要特征分量,常用于高维数据的降 ...

  10. 使用js将后台返回的数据转换成树形结构

    将类似如下数据转换成树形的数据: [ { id: 1, name: '1', }, { id: 2, name: '1-1', parentId: 1 }, { id: 3, name: '1-1-1 ...