C语言的lex和yacc工具说明

2024-04-17 18:38
文章标签 语言 工具 说明 yacc lex

本文主要是介绍C语言的lex和yacc工具说明,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Lex工具 
------- 
Lex工具是一种词法分析程序生成器,它可以根据词法规则说明书的要求来生成单词识别程序,由该程序识别出输入文本中的各个单词。 
1、lex程序的结构 

-定义部分 
-规则部分 
-用户子程序部分 

其中规则部分是必须的,定义和用户子程序部分是任选的。 

(1) 定义部分 
定义部分起始于"%{"符号,终止于"%}"符号,其间可以是包括include语句、声明语句在内的C语句。 
%{ 
#include "stdio.h" 
#include "y.tab.h" 
extern int lineno; 
%} 

(2) 规则部分 
规则部分起始于"%%"符号,终止于"%%"符号,其间则是词法规则。词法规则由模式和动作两部分组成。模式部分可以由任意的正则表达式组成,动作部分是由C语言语句组成,这些语句用来对所匹配的模式进行相应处理。需要注意的是,lex将识别出来的单词存放在yytext[]字符数据中,因此该数组的内容就代表了所识别出来的单词的内容。 

%% 
[/t] {;} 
[0-9]+/.?[0-9]*/.[0-9]+ 
{ sscanf(yytext,"%1f", &yylval.val); 
return NUMBER; } 
/n { lineno++;return ''/n''; } 
. { return yytex+[0]; } 
%% 

(3) 用户子程序部分 
用户子程序部分可以包含用C语言编写的子程序,而这些子程序可以用在前面的动作中,这样就可以达到简化编程的目的。下面是带有用户子程序的lex程序片段。 
"/*" skipcmnts(); 
. /* rest of rules */ 
%% 
skipcmnts() 
{ 
for ( ; ; ) 
{ 
while (input()!=''*''); 
if(input()!=''/'') 
unput(yytext[yylen-1]); 
else return; 


2、lex工具的使用方法 
首先编写一个lex程序 
vi lex.l 
%{ 
#include "stdio.h" 
%} 
%% 
[/n] ; 
[0-9]+ printf("Interger: %s /n",yytext); 
[0-9]*/.[0-9]+ printf("Float: %s/n",yytext); 
[a-zA-Z][a-zA-Z0-9]* printf("Word:%s/n",yytext); 
. printf("Other symbol:%c/n",yytext[0]); 
%% 

然后使用lex将lex.l转换成C语言程序 
$lex lex.l 
使用上述命令产生的C语言程序为lex.yy.c 
然后使用C编译程序将lex.yy.c编译成可执行程序regn 
$cc -c lex.yy.c 
$cc lex.yy.o -ll -o regn 
下面可以使用regn来识别单词 
$vi testfile 
x=355 
y=113 
p=x/y 

# ./regn < testfile 
Word:x 
Other symbol:= 
Interger: 355 
Word:y 
Other symbol:= 
Interger: 113 
Word:p 
Other symbol:= 
Word:x 
Other symbol:/ 
Word:y 


yacc工具 
-------- 
yacc工具是一种语法分析程序生成器,它可以将有关某种语言的语法说明书转换成相应的语法分析程序,由该程序完成对相应语言中语句的语法分析工作。 

1、yacc程序结构 
在使用yacc工具前,必须首先编写yacc程序,因为有关语法分析程序是根据yacc程序生成的。yacc程序实际上是有关语法规则的说明书,它也是由定义部分、规则部分和子程序部分组成的。yacc程序的定义部分类似于lex程序的定义部分,只是在其后可带有yacc声明,其中包括词法单词、语法变量、优先级和结合性信息。yacc程序的规则部分由语法规则和相应的动作组成,子程序部分可以包括在前面规则部分用到的子程序定义。接下来是main主程序,它调用yyparse子程序来对输入进行语法分析,而yyparse反复地调用yylex子程序来获得输入单词,在语法出错时可通过yyerror子程序来处理。 

2、yacc工具的使用方法 
实例:我们将yacc程序分成片段,把这些片段组合在一起就是yacc程序。我们要使用的语法规则是一个有关四则运算的语法规则,可用BNF范式描述 
list: expr /n 
list expr /n 
expr :NUMBER 
expr + expr 
expr - expr 
expr * expr 
expr / expr 
(expr) 
其含义是list是一个表达式序列,每个后面带有一个新行。表达式是一个数值,或是由运算符连起来的两个表达式,以及用圆括号括起来的表达式。 
下面是有关上述语法规则的yacc程序片段。 
$vi hoc.y 
%{ 
#define YYSTYPE double 
%} 
%token NUMBER 
%left ''+'' ''-'' 
%left ''*'' ''/'' 
%% 
list: 
list ''/n'' 
list expr ''/n'' { printf("/t%. 8g/n",$2);} 

expr : NUMBER {$$=$1;} 
expr ''+'' expr {$$ = $1 + $3; } 
expr ''-'' expr {$$ = $1 - $3; } 
expr ''*'' expr {$$ = $1 * $3; } 
expr ''/'' expr {$$ = $1 / $3; } 
''(''expr'')'' {$$ = $2; } 
%% 
上述yacc程序片段实际上是它的定义部分和规则部分。在yacc声明部分,%token NUMBER表明了NUMBER是一个单词符号,%left则表明了运算符号的左结合性,并且''*''和''/''和优先级比''+''和''-''的优先级高。在yacc程序的规则部分,备用规则是用''''隔开的,规则中的动作实际上是C语句序列,其中$n(即$1,$2等)是用来引用规则中的第几个成份,而$$则代表了整个规则的返回值。 

下面的yacc程序片段是main主程序 
#include <stdio.h> 
#include <ctype.h> 
char *progname; 
int lineno=1; 
main(argc,argv) 
int argc; 
char *argv[]; 
{ progname = argv[0]; 
yyparse(); 


main主程序调用yyparse子程序来处理来处理输入,而yyparse又是通过yylex子程序来获得输入单词并通过yyerror子程序来报告出错信息。下面是有关这两个子程序的yacc程序片段 

yylex() 
{ int c; 
while ((c=getchar()) == '' '' c==''/t'') ; 
if (c==EOF) 
return 0; 
if (c==''.''isdigit(c)){ 
ungetc(c,stdin); 
scanf("%lf", &yylval); 
return NUMBER; 

if(c==''/n'') 
lineno++; 
return c; 

yyerror(s) 
char *s; 
{ warning (s,(char *)0); 

warning(s,t) 
char *s,*t; 
{ fprintf(stderr,"%s:%s",progname,s); 
if(t) 
fprintf(stderr,"%s",t); 
fprintf(stderr," near line %d/n",lineno); 


这样就完成了整个yacc程序 
接下来就使用 yacc将hoc.y转换成C语言程序 
$yacc hoc.y 
使用上述命令产生的C语言程序为y.tab.c,这时可以使用C编译程序将它编译成可执行程序hoc. 
$cc y.tab.c -o hoc 

下面是使用hoc的例子 
# ./hoc 
4*3*2 
24 
(1+2)*(3+4) 
21 
1/2 
0.5 
355/133 
2.6691729 
-3-4 
./hoc:Syntax error near line 5 
上述结果显示中,分别表明了计算结果,最后一次计算出错的原因是由于在规则定义中未来定义单目减运算符号。

这篇关于C语言的lex和yacc工具说明的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/912540

相关文章

Zookeeper安装和配置说明

一、Zookeeper的搭建方式 Zookeeper安装方式有三种,单机模式和集群模式以及伪集群模式。 ■ 单机模式:Zookeeper只运行在一台服务器上,适合测试环境; ■ 伪集群模式:就是在一台物理机上运行多个Zookeeper 实例; ■ 集群模式:Zookeeper运行于一个集群上,适合生产环境,这个计算机集群被称为一个“集合体”(ensemble) Zookeeper通过复制来实现

高效录音转文字:2024年四大工具精选!

在快节奏的工作生活中,能够快速将录音转换成文字是一项非常实用的能力。特别是在需要记录会议纪要、讲座内容或者是采访素材的时候,一款优秀的在线录音转文字工具能派上大用场。以下推荐几个好用的录音转文字工具! 365在线转文字 直达链接:https://www.pdf365.cn/ 365在线转文字是一款提供在线录音转文字服务的工具,它以其高效、便捷的特点受到用户的青睐。用户无需下载安装任何软件,只

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

超强的截图工具:PixPin

你是否还在为寻找一款功能强大、操作简便的截图工具而烦恼?市面上那么多工具,常常让人无从选择。今天,想给大家安利一款神器——PixPin,一款真正解放双手的截图工具。 想象一下,你只需要按下快捷键就能轻松完成多种截图任务,还能快速编辑、标注甚至保存多种格式的图片。这款工具能满足这些需求吗? PixPin不仅支持全屏、窗口、区域截图等基础功能,它还可以进行延时截图,让你捕捉到每个关键画面。不仅如此

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

log4j2相关配置说明以及${sys:catalina.home}应用

${sys:catalina.home} 等价于 System.getProperty("catalina.home") 就是Tomcat的根目录:  C:\apache-tomcat-7.0.77 <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c{1}:%L - %msg%n" /> 2017-08-10

MiniGPT-3D, 首个高效的3D点云大语言模型,仅需一张RTX3090显卡,训练一天时间,已开源

项目主页:https://tangyuan96.github.io/minigpt_3d_project_page/ 代码:https://github.com/TangYuan96/MiniGPT-3D 论文:https://arxiv.org/pdf/2405.01413 MiniGPT-3D在多个任务上取得了SoTA,被ACM MM2024接收,只拥有47.8M的可训练参数,在一张RTX