Lex和Yacc使用学习笔记(二)

LexYacc应用方法().再识LexYacc LexYacc应用方法().再识LexYacc草木瓜  20070314早在十世记七十年代之前,编写编译器一直是一个非常费时的工作。但到了1975这一年这一切却发生了重大转变,首先Stephen C. Johnson Lesk在贝尔实验室完成了Yacc开发,为了配合yacc更好的协作, Mike LeskEric Schmidt又完成了lex。从而Lexyacc成为计算机编译领 阅读详情

Yacc

       yacc的文法由一个使用BNF文法(Backus-Naur form 的变量描述。文法规则最初由 John Backus Peter Naur 发明,并且用于描述Algol60 语言。 BNF 能够用于表达上下文无关语言。现代程序语言中的大多数结构可以用BNF 文法来表达。例如,数值相乘和相加的文法是:

E > E + E

E > E * E

E > id

E (表达式)这样出现在左边的结构叫非终结符(nonterminal)。像 id(标识符)这样的结构叫终结符(terminal,由lex 返回的标记),它们只出现在右边。

yacc的输入文件格式与lex类似,给出一个例子,计算加减乘除的简单计算器,yacclex结合使用。

 

Lex的输入文件:

%{

/****************************************************************************

calclexer.l

ParserWizard generated Lex file.

 

Date: 20081013

****************************************************************************/

#include <stdlib.h>

void yyerror(char *);

#include "calcparser.h"

extern YYSTYPE yylval;

%}

 

/////////////////////////////////////////////////////////////////////////////

// declarations section

 

// place any declarations here

 

%%

 

/////////////////////////////////////////////////////////////////////////////

// rules section

 

// place your Lex rules here

[0-9]+     {

                     yylval = atoi(yytext);

                     return INTEGER;

              }

[-+*//n]   return *yytext;

[ /t]  ; /* skip whitespace */

.             yyerror("invalid character");

%%

 

/////////////////////////////////////////////////////////////////////////////

// programs section

 

int yywrap(void) {

return 1;

}

Yacc的输入文件:

%{

/****************************************************************************

calcparser.y

ParserWizard generated YACC file.

 

Date: 20081013

****************************************************************************/

 

#include "calclexer.h"

int yylex(void);

void yyerror(char *);

%}

 

/////////////////////////////////////////////////////////////////////////////

// declarations section

 

// attribute type

%include {

#ifndef YYSTYPE

#define YYSTYPE int

#endif

}

 

// place any declarations here

%token INTEGER

%left '+' '-'

%left '*' '/'

%%

 

/////////////////////////////////////////////////////////////////////////////

// rules section

 

// place your YACC rules here (there must be at least one)

 

program:

       program expr '/n' { printf("%d/n", $2); }

       |

       ;

expr:

       INTEGER { $$ = $1; }

       | expr '+' expr { $$ = $1 + $3; }

       | expr '-' expr { $$ = $1 - $3; }

       | expr '*' expr { $$ = $1 * $3; }

       | expr '/' expr { $$ = $1 / $3; }

       ;

%%

 

/////////////////////////////////////////////////////////////////////////////

// programs section

 

void yyerror(char *s)

{

       fprintf(stderr, "%s/n", s);

}

 

int main(void)

{

       yyparse();

       return 0;

}

需要注意以下几点:

l         在计算+-的时候,文法本身是有移近-规约冲突(shift-reduce conflict)的,例如10-2-2,到底是先计算10-2,还是先计算2-2。默认是移近,就会先计算2-2,结果是不正确的。可以通过%left%right指定结合顺序来解决冲突,即【%left '+' '-' 】,最后列出的定义拥有最高的优先权。因此乘法和除法拥有比加法和减法更高的优先权。

l         yylval是在yacc的输出文件中定义的,在lex中使用时需要先用extern将其引入【extern YYSTYPE yylval;

l         yacc 在内部维护着两个堆栈;一个分析栈和一个内容栈。分析栈中保存着终结符和非终结符,并且代表当前剖析状态。内容栈是一个YYSTYPE 元素的数组,对于分析栈中的每一个元素都保存着一个对应的值。例如,当yylex 返回一个INTEGER 标记时,yacc 把这个标记移入分析栈。同时,相应的yylval 值将会被移入内容栈中。分析栈和内容栈的内容总是同步的,因此从栈中找到对应于一个标记的值是很容易实现的。

LexYacc从入门到精通(4)-能够使用C++的LexYacc框架 能够使用C++的LexYacc框架 本文版权归熊春雷所有 ,我的邮箱:pandaxcl@163.com>,欢迎大家我讨论计算机方面 的问题,在我的博客上 面还写了很多其他的文档,有空来看看哦。如果转载,请保留此版权信息,并注 明出处。谢谢:) 摘要 写这一章的目的就是为了能够提供一个能够使用C++特色的LexYacc框架,这个 阅读详情

相关推荐

LexYacc使用教程().Windows下使用LexYacc

LexYacc应用方法().Windows下使用LexYacc草木瓜  20070904一、序    不想LexYacc系列的最后一篇文章竟如此“难产”,已时隔三个月之久。不由慨叹自由可支配时间是如此之少,如此岂不谓新时代的“奴隶”~    罢罢罢,闲话少叙,回归正题,本文主要介绍在Windows下如何去使用LexYacc,以作为本系列文章的终结。    、方法介绍  

草木瓜 2万+

linux下lex程序例子,一个Lex/Yacc完整的示例(使用C++)

作者: 胡彦 2013-4-28本例子虽小却演示了lex/yacc程序最重要常用的特征:* lex/yacc程序组成结构、文件格式。* 如何在lex/yacc使用C++STL库,用extern "C"声明那些lex/yacc生成的、要链接的C函数,如yylex(), yywrap(), yyerror()。* 重定义YYSTYPE/yylval为复杂类型。* lex里多状态的定义使用,用B...

weixin_29534143的博客 969

【PLY】LexYacc简单示例

PLY是流行的编译器构造工具lexyacc的纯python实现。 PLY官方文档:http://www.dabeaz.com/ply/ PLY文档翻译:https://qyliang.blog.csdn.net/article/details/97686897 PLY由两个单独的模块组成lex.py yacc . py 。都可以在名为ply的Python包中找到。 lex.py模块用于将输入的...

土豆洋芋山药蛋的博客 3043

yacc&lex-调用C++代码

要点用lex&yacc命令缺省生成的是C文件,但事实上,仅是文件扩展名表示为C文件。可以用g++或者直接改名为C++就可以在lex&yacc中用C++功能。

A Flying Bird 1331

lexyacc()计算器的实现

构建一个c语言的编译器并不是一件容易的事,我想每个人在学习编译原理的时候并不会常见得它非常简单. 下面将会学习编译器的两个重要组成部分:词法分析器flex语法分析器yacc flex是gun实现的fast lex(lexical anslysis) yacc实现有gun的

向开源软件的开发者们致敬 5531

编译原理——LexYacc及应用

一. 实验原理: Lex(Lexical Analyzar 词法分析生成器)Yacc(Yet Another Compiler Compiler 编译器代码生成器)是Unix下十分重要的词法分析,语法分析的工具。经常用于语言分析,公式编译等广泛领域。 Lex工具是一种词法分析程序生成器,它可以根据词法规则说明书的要求来生成单词识别程序,由该程序识别出输入文本中的各个单词。 一般可以分为<定义部分><规则部分><用户子程序部分>。其中规则部分是必须的,定义用户子程序部

TTTSEP9TH2244的博客 5977

lex+yacc 构造语法树(

上一章我们已经写好了lex.l文件,接下来我们还要根据归约规则来确定所得到的token是由上一级的哪些token展开而成。 我们需要构造的small C语言的语法规则如下: 归约规则的声明格式参照yacc的格式,需要注意的是声明符号的左结合或右结合的时候要注意符号的优先级。 %{ #include #include #include #include "lex.yy.c"

字传 5497

LexYacc应用方法().初识Lex

 LexYacc应用方法().初识Lex草木瓜  20070301Lex(Lexical Analyzar 词法分析生成器)Yacc(Yet Another Compiler Compiler编译器代码生成器)是Unix下十分重要的词法分析,语法分析的工具。经常用于语言分析,公式编译等广泛领域。遗憾的是网上中文资料介绍不是过于简单,就是跳跃太大,入门参考意义并不大。本文通过循序渐进的

草木瓜 5万+

编译原理——Lexyacc的安装

Lexyacc的安装 Linux用户 LexYacc可以直接从终端安装,命令: apt install flex bison 部分系统可能还需要手动安装 gcc make 等工具,请自行测试。 安装完成后,在终端输入以下命令,若可以正确显示出版本号,则安装成功。 gcc --version lex --version yacc --version 如图所示:(图片来源网络)...

budding0828 1万+

能够使用C++的LexYacc框架

能够使用C++的LexYacc框架<br />写这一章的目的就是为了能够提供一个能够使用C++特色的LexYacc框架,这个框架同前一章的目的一样,也是仅仅为了能够提供一个什么也不作的框架程序,当时有点不同的就是:这个新的框架使用了C++语法,能够使用所有的C++特色,包括STL的强劲算法容器,还有各式各样的C++库。采用C++的目的就是为了能够快速的编码来完成自己需要完成的任务。<br />在编码词法分析语法分析程序的时候经常会编写一些链表容器,实际上这些链表容器在C++语言函数库里面都已经有

Skai_CSDN的专栏 2244

lexyacc程序学习(4)——lexyacc使用

一个程序通常在每次返回一个标记时都要调用yylex()函数。只有在文件结束或者出现错误标记时才会终止。 一个由yacc生成的分析器调用yylex()函数来获得标记。yylex()可以由Lex来生成或完全由自己来编写。对于由Lex生成的lexer来说,要yacc结合使用,每当Lex中匹配一个模式时都必须返回一个标记。因此Lex中匹配模式时的动作一般格式为: {pattern} { /* do smthg*/ return TOKEN_NAME; } 于是 Yacc 就会获得返回的标记。当 Yacc

wang_yr的博客 1145

YaccLex 快速入门

简介: Lex Yacc 是 UNIX 两个非常重要的、功能强大的工具。事实上, 如果你熟练掌握 Lex Yacc 的话,它们的强大功能使创建 FORTRAN C 的编译器如同儿戏。本文详细的讨论了编写自己的语言编译器所 用到的这两种工具,包括常规表达式、声明、匹配模式、变量、Yacc 语 法解析器代码。最后,本文解释了怎样把 Lex Yacc 结合起来。

红孩儿编程大师 4491

yacc lex c 注释_LexYACC详解

原文:https://www.cnblogs.com/hdk1993/p/4922866.html注:1)修正了原文中有问题的代码;2)补充了YY_INPUT等内容。一、简介只要你在Unix环境中写过程序,你必定会邂逅神秘的Lex&YACC,就如GNU/Linux用户所熟知的Flex&Bison,这里的Flex就是由Vern Paxon实现的一个Lex,Bison则是GNU版本的Y...

weixin_39632397的博客 1465

基于Lex Yacc 的 C 语言编译器

最近由于项目需要,看了点关于编译原理编译器等方面的资料,特别是词法分析语法分析部分,现做一下小结。 一、编译器及其工作流程 编 译器,是将便于人编写,阅读,维护的高级计算机语言翻译为计算机能识别,运行的低级机器语言的程序。编译器将源程序(Source program)作为输入,翻译产生使用目标语言(Target language)的等价程序。源程...

JennyComputer2014的博客 1423

LexYacc入门

原文地址:http://coanor.blog.hexun.com/38241166_d.html   1. 简介 只要你在Unix环境中写过程序,你必定会邂逅神秘的Lex&YACC,就如GNU/Linux用户所熟知的Flex&Bison,这里的Flex就是由Vern Paxon实现的一个Lex,Bison则是GNU版本的YACC.在此我们将统一称呼这些程序为LexYACC.新版本的程序是

雜貨鋪 2108

LEXYACC简介

Lex工具 -------     Lex工具是一种词法分析程序生成器,它可以根据词法规则说明书的要求来生成单词识别程序,由该程序识别出输入文本中的各个单词。 1、lex程序的结构 -定义部分 -规则部分 -用户子程序部分 其中规则部分是必须的,定义用户子程序部分是任选的。 (1) 定义部分      定义部分起始于"%{"符号,终止于"%}"符号,其间可以是包括include语句、声明语句在内的C语句。 %{ #include "stdio.h" #include "y.tab.h" extern in

xiaoxiaofengqi的专栏 5453

Lex+YACC or Flex+Bison

1.简介 只要你在Unix环境中写过程序,你必定会邂逅神秘的Lex&YACC,就如GNU/Linux用户所熟知的Flex&Bison,这里的Flex就是由Vern Paxon实现的一个Lex,Bison则是GNU版本的YACC. 在此我们将统一称呼这些程序为LexYACC.新版本的程序是向上兼容的(译注:即兼容老版本),所以你可以用FlexBis...

zzhongcy的专栏 3591
上一篇: Lex和Yacc使用学习笔记(一)
下一篇: RSA数字签名和加解密
flying2
博客等级 码龄24年 4粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值