文档章节

LEX学习 第二节

陈洪波
 陈洪波
发布于 2015/05/19 19:36
字数 1014
阅读 36
收藏 0

接着第一节中的第一个示例,我们扩展第二个示例,将词法分析程序扩展为识别不同的词性。
下面是程序示例:

%{
/*
 * 扩展第一个示例以识别其他的词性
 *
 */
%}

%%
[ \t ]+  /* 忽略空白 */;
is |
am |
are |
were |
was |
be |
being |
been |
do |
does |
did |
will |
would |
should |
can |
could |
has |
had |
go {printf("%s: is a verb",yytext);}

very |
simply |
gently |
quietly |
calmly |
angrily {printf("%s: is an adverb",yytext);}

to |
from |
behind |
above |
below |
between {printf("%s: is a preposition",yytext);}

if |
then |
and |
but |
or {printf("%s: is a conjunction",yytext);}

their |
my |
your |
his |
her |
its {printf("%s : is an adjection",yytext);}

I |
you |
he |
she |
we |
they {printf("%s: is a pronoun",yytext);}

[a-zA-Z]+ {
    printf("%s: do not recognize,mignt be a noun",yytext);
}

.| {ECHO; /* 通常的默认状态 */}

%%

int main()
{
    yylex();
    return 0;
}

int yywrap()
{
    return 1;
}

第二个示例实际上与第一个没有什么不同,仅仅就是列出了比前面更多的单词,原则上可以扩展这个示例为任意多的单词。但是这样感觉有些笨拙,如果是单词比较多的话,就需要将所有的单词都要列出来,如果能够有一个单词表,能够实时的添加新的单词的话,扩展性上就会好很多。下面我们再扩展一下,就是在词法分析程序运行时从输入文件中读取声明的单词时允许动态的声明词性。声明行以词性的名称开始,后面跟着要声明的单词。例如:
声明4个名词和3个动词:
noun dog cat horse cow
verb chew eat lick

该单词表在lex和yacc中就是一个简单的符号表,添加符号表可以完全改变词性语法分析程序,不必在词法分析程序中为每个要匹配的单词放置独立的模式,只要有一个匹配任意单词的模式,再查阅符号表就能决定所找到的词性。由于词性引入了一个声明行,所以他们现在是”保留字“。对于每一个保留字仍然有一个独立的lex模式。还必须添加符号表维护例程。add_word()表示添加单词,lookup_word()表示查询单词。

同时在程序代码中需要一个state变量用来记录是查找单词还是添加单词。无论如何只要我们看到以词性名字开始的行,就可以知道状态为添加单词,每次看到\n的时候,都切换回正常的查找状态。

下面是程序的实现:

%{
    /* * 带符号表的单词识别程序 */
    enum{
        LOOKUP = 0, /* 默认-查找而不是定义 */
        VERB,
        ADJ,
        ADV,
        NOUN,
        PREP,
        PRON,       
        CONJ    
    };

    int state;

    int add_word(int type,char *word);
    int lookup_word(char *word);
%}

%%

 {state = LOOKUP;} /* 行结束,返回默认状态 */
    /* 无论何时return wp->word_type,行都以保留的词性名字开始 */
    /* 开始定义该类型的单词 */
^verb {state = VERB; }
^adj  {state = ADJ;  }
^adv  {state = ADV;  }
^noun {state = NOUN; }
^prep {state = PREP; }
^pron {state = PRON; }

[a-zA-Z]+ {
    /* 一个标准的单词,定义他或查找它 */
    if(state != LOOKUP){
        /* 定义当前单词 */
        add_word(state,yytext);
    }else{
        switch(lookup_word(yytext)){
            case VERB: printf("%s: verb",yytext); break;
            case ADJ:  printf("%s: adjective",yytext); break;
            case ADV: printf("%s: adverb",yytext); break;
            case NOUN: printf("%s: noun",yytext); break;
            case PREP: printf("%s: preposition",yytext); break;
            case PRON: printf("%s: pronoun",yytext); break;
            case CONJ: printf("%s: conjunction",yytext); break;
            default:
                printf("%s: do not recognize",yytext);
                break;
        }
    }
}
. /* 忽略其他return wp->word_type的东西 */

%%

int main()
{
    yylex();
    return 0;
}

/* 定义一个单词和类型的链表 */
struct word{
    char *word_name;
    int word_type;
    struct word *next;
};

struct word *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",word);
        return 0;
    }

    /* 单词不在那里,分配一个新的条目并将它链接到链表上 */
    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;
    }
    return LOOKUP;
}

int yywrap()
{
    return 1;
}

下面是我的程序的输出结果:
这里写图片描述

本文转载自:http://blog.csdn.net/hongbochen1223/article/details/45726355

陈洪波
粉丝 2
博文 76
码字总数 1552
作品 0
济南
程序员
私信 提问
手把手教你通过游戏解决交通拥堵丨MIT深度学习公开课

被堵在路上是件心累又烧钱的事儿,除了让人头疼还可能错过重要的约会。据统计,美国每年因交通堵塞的直接损失达到 780 亿美元。今年,MIT 推出了深度学习公开课,试图让学生们在模拟游戏中尝...

Data Analyst
2017/08/18
0
0
如何开始深度学习?麻省理工开源了一份入门级课程(MIT 6.S094中译版)

2018 MIT 6.S094 官方授权翻译的中文字幕版,终于来了 ! 近日,麻省理工学院(MIT)开源了 2018 年最新版「MIT 6.S094:深度学习和自动驾驶」。雷锋字幕组 获MIT官方授权翻译,4 月 13 日正...

雷锋字幕组
2018/04/13
0
0
学习 JFlex 和 BYacc/J 简要笔记

JFlex 是 The Fast Lexical Analyser Generator, 是 lex/flex 的 java 版本, JLex 的升级. 帮助手册地址: http://www.jflex.de/manual.html 中文的一些资料: http://wenku.baidu.com/view/5......

刘军兴
2014/01/01
0
4
Flex Manual基础笔记2

http://flex.sourceforge.net/manual/ 说明:发现这个manual太罗嗦了,要是按照它的思路下去,我的笔记又成为了翻译。果断跳过,还是从例子开始来学习比较好,先弄出例子,然后看需要什么功能...

shenghong
2012/02/19
0
0
从0行代码开发房卡棋牌(麻将等)系列教程

本课程从0开始讲解如何使用cocoscreator和nodejs打造商业级别的×××。课程由简入深的进行,课程学习完成后,基本具备了开发任意×××的能力。除此之外,最具核心竞争力的是,本系统支持人...

李鸡蛋
2017/12/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

idea下springboot 项目在static目录下添加文件不生效

idea下springboot 项目在static目录下添加文件不生效 问题描述 是这样子的,我的项目目录结构如下: 我在static目录下,创建了index.html和aaaa.jpg这两个文件。然后,启动服务访问 http://l...

wotrd
昨天
5
0
k8s1.14 一、环境

1. 4台虚拟机 (CentOS Linux release 7.2.1511 (Core) ) 192.168.130.211 master 192.168.130.212 node1 192.168.130.213 node2 192.168.130.214 node3 2. 设置服务器hostname 2.1 设置本机......

ThomasCheng
昨天
3
0
盖茨:如果我现在开创一家公司 将会专注于AI

新浪科技讯,北京时间 6 月 26 日凌晨消息,微软联合创始人比尔·盖茨(Bill Gates)在周一接受采访时表示,如果他今天从哈佛大学辍学并开创一家新公司,那么这家公司将会专注于人工智能(A...

linuxCool
昨天
1
0
聊聊feign的Retryer

序 本文主要研究一下feign的Retryer Retryer feign-core-10.2.3-sources.jar!/feign/Retryer.java public interface Retryer extends Cloneable { /** * if retry is permitted, retur......

go4it
昨天
10
0
HyperLogLog简介

  (1)HyperLogLog简介      在Redis 在 2.8.9 版本才添加了 HyperLogLog,HyperLogLog算法是用于基数统计的算法,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个...

SEOwhywhy
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部