Lex与Yacc学习(三)之符号表
符号表
列举单词表的方式虽然简单但是不全面,如果在词法分析程序运行时可以构建一个单词表,那么就可以在添加新的单词时不用修改词法分析程序。
下面示例便利用符号表实现,即在词法分析程序运行时从输入文件中读取声明的单词时允许动态的声明单词。声明以词性的名字开始,后面跟着要声明的单词。
添加符号表可以完全的改变词法分析程序,不必在词法分析程为每个要匹配的单词放置独立的模式,只要有一个匹配任意单词的模式,再查阅符号表就能决定所找到的词性。
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学习(三)之符号表的更多相关文章
- Lex与Yacc学习(一)之环境配置篇
Abstract 在开发程序的过程中经常会遇到文本解析的问题,例如:解析 C 语言源程序,编写 脚本引擎等等,解决这种文本解析的方法有很多,一种方法就是自己手动用 C 或者 C++直接编写解析程序,这 ...
- Lex与Yacc学习(九)之Yacc语法
Yacc语法 本文讨论yacc语法的格式并描述可用的各种特征和选项 yacc语法结构 yacc语法包括三部分:定义段.规则段和用户子例程段 ...定义段... %% ...规则段... %% ...用 ...
- Lex与Yacc学习(四)之Lex规范
Lex规范的结构 lex程序由三部分组成:定义段.规则段和用户子例程序段 ...定义段... %% ...规则段... %% ...用户子例程序段... 这些部分由以两个百分号组成的行分隔开.尽管某一 ...
- Lex与Yacc学习(十)之Yacc库
Yacc库 每个实现都需要有用的例程库,在UNIX系统中,可以通过cc命令行尾端给出-ly标志(或通过其他系统下的等价物)来包含库. 库的内容在不同的实现之间是不同的,但总是包括main()和yyer ...
- Lex与Yacc学习(六)之lex & yacc (简单计算器程序) 运行
词法分析程序ch3-01.l %{ #include "ch3-01.tab.h" extern int yylval; %} %% [0-9]+ { yylval = atoi( ...
- Lex与Yacc学习(五)之正则表达式篇
正则表达式语法 lex模式是由编辑程序和实用程序使用的正则表达式的扩展版本.正则表达式由常规字符(代表它们本身)和元字符(在一种模式中具有特殊含义)组成. 元字符 . . 匹配除了换行符 \n 之外的 ...
- Hibernate学习(三)自动建表
一般情况下有如下两种方法: 1.在配置文件中添加如下配置 <property name="hibernate.hbm2ddl.auto">create</prop ...
- Lex与Yacc学习(二)之第一个Lex程序
用lex识别单词 构建一个识别不同类型英语单词的简单程序.先识别词性(名词,动词等),然后再扩展到处理符合简单英语语法的多个单词的句子. 先列出要识别的一组动词: is am are w ...
- Lex与Yacc学习
http://www.cnblogs.com/shine-yr/p/5214976.html
随机推荐
- POJ-1181-食物链
链接:https://vjudge.net/problem/POJ-1182 题意: 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1 ...
- 去除List<Object>集合中重复的元素(利用HashSet的特性---无重复元素)
import java.util.ArrayList;import java.util.HashSet;import java.util.Iterator; public class Hashset ...
- elastcisearch中文分词器各个版本
地址 https://github.com/medcl/elasticsearch-analysis-ik/releases?after=v6.0.1
- SQL Server 查看列,添加列,修改列,删除列
查看表:exec sp_help 表名 查看列: exec sp_columns 表名 查看列:select * from information_schema.columns where table ...
- 代码review
对于代码review个人也有些小小的看法: 1.首先我觉得我们所有开发人员要弄明白 现在Code Review 的目的 ,凡事不弄明白目的,无法做好完成一件事情,个人觉得有以下一些目的: a)可以在项 ...
- Java编程基础-选择和循环语句
一.选择结构语句 选择结构:也被称为分支结构.选择结构有特定的语法规则,代码要执行具体的逻辑运算进行判断,逻辑运算的结果有两个,所以产生选择,按照不同的选择执行不同的代码. Java语言提供了两种选择 ...
- vue样式操作与事件绑定
Vue笔记 1 Vue实例 (VM) var vm = new Vue({ el:'#app', //挂载元素 //数据 data: { title:'值', ...
- CF747D Winter Is Coming
题目链接: http://codeforces.com/problemset/problem/747/D 题目大意: 接下来的n天内每天都有一个气温,如果某天的温度为负数,则必须使用冬季轮胎:而温度 ...
- (转)UVM挑战及概述
UVM的调度也具有其独特的挑战,尤其是在调试的领域.其中的一些挑战如下: 1. Phase的管理:objections and synchronization 2. 线程调试 3. Tracing i ...
- 将centos6的php5.3升级为5.6
在阿里云主机上,操作系统是Centos6,php版本是5.3.因为安装Yii2.0的需要,我要升级php为5.4.因为还有5.5和5.6,当然要升到高版本了.我决定升到5.6. 首先,按照这里的步 ...