利用Flex自动生成C语言词法分析器

  • Flex介绍
  • C语言词法规则
  • 具体实现
    • 源代码
    • 测试代码
    • 实验结果

Flex介绍

  1975年Mike Lesk和实习生Eric Schmidt设计并实现了一个词法分析器lex(lexical analyzer generator),其中大部分的实现工作是由Schmidt完成的。lex既可以独立使用也可以与Johnson的yacc配合使用。虽然lex运行比较慢并且也不太稳定,但是应用还是非常广泛。Schmidt后来担任了Google的CEO。大约1987年左右,Lawrence Berkeley实验室的Vern Paxson将使用ratfor语言(一种Fortran扩展语言)编写的一个lex版本翻译成了C版本,并重新命名为flex(Fast Lexical Analyzer Generator)。这个版本比AT&T版本的lex更快更稳定,并使用了Berkeley开源协议,因此取代了原来的lex。
  Flex源文件的编写很容易上手,指路lex源文件结构。
  在Ubuntu系统直接安装flex的命令为:sudo apt-get install flex
  

C语言词法规则

  以C11为基准,对C语言的词法规则进行简要的描述。
(1)C语言的关键字包括如下单词:

(2)C语言标识符的定义如下:

(3)C语言整型常量的定义如下:

(4)C语言浮点型常量定义如下:

(5)C语言字符常量定义如下:

(6)C语言字符串字面量定义如下:

(7)C语言运算符和界限符定义如下:

  

具体实现

源代码

  编写flex文件:Scan.l

%{#include<stdio.h>#include<stdlib.h>#include<string.h>int num=1; int line=1;int col=1;
%}keyword auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|whileidentifier ({nondigit}|_)({nondigit}|_|{digit})*
nondigit [a-zA-Z]
digit [0-9]integer_constant ({decimal_constant}|{octal_constant}|{hexadecimal_constant}){integer_suffix}
decimal_constant {nonzero_digit}{digit}*
octal_constant 0{octal_digit}*
hexadecimal_constant {hexadecimal_prefix}{hexadecimal_digit}+
hexadecimal_prefix 0x|0X
nonzero_digit [1-9]
octal_digit [0-7]
hexadecimal_digit [0-9a-fA-F]
integer_suffix ({unsigned_suffix}{long_suffix})|({unsigned_suffix}{long_long_suffix})|({long_suffix}{unsigned_suffix})|({long_long_suffix}{unsigned_suffix})
unsigned_suffix u|U
long_suffix l|L
long_long_suffix ll|LLfloating_constant {decimal_floating_constant}|{hexadecimal_floating_constant}
decimal_floating_constant {fractional_constant}{exponent_part}{floating_suffix}|{digit_sequence}{exponent_part}{floating_suffix}
hexadecimal_floating_constant {hexadecimal_prefix}{hexadecimal_fractional_constant}{binary_exponent_part}{floating_suffix}|{hexadecimal_prefix}{hexadecimal_digit_sequence}{binary_exponent_part}{floating_suffix}
fractional_constant {digit_sequence}\.{digit_sequence}|{digit_sequence}\.
exponent_part [eE]{sign}{digit_sequence}
sign [+-]
digit_sequence {digit}+
hexadecimal_fractional_constant {hexadecimal_digit_sequence}\.{hexadecimal_digit_sequence}|{hexadecimal_digit_sequence}\.
binary_exponent_part [pP]{sign}{digit_sequence}
hexadecimal_digit_sequence {hexadecimal_digit}+
floating_suffix [flFL]character_constant [uUL]?\'{c_char_sequence}\'
c_char_sequence {c_char}+
c_char [^\\\'\n]|{escape_sequence}
escape_sequence {simple_escape_sequence}|{octal_escape_sequence}|{hexadecimal_escape_sequence}
octal_escape_sequence \\{octal_digit}{1,3}
hexadecimal_escape_sequence \\x{hexadecimal_digit}{1,2}
simple_escape_sequence \\\'|\\\"|\\\?|\\\\|\\a|\\b|\\f|\\n|\\r|\\t|\\vstring_literal {encoding_prefix}?\"{s_char_sequence}\"
encoding_prefix u8|u|U|L
s_char_sequence {s_char}+
s_char [^\\\'\n]|{escape_sequence}opt ("+"|"-"|"*"|"/"|"+="|"-="|"*="|"/="|">="|"<="|"=="|">"|"<"|"="|"++"|"--")
bracket ("("|")"|"["|"]"|"{"|"}"|";"|","|"\'"|"\""|"#") %%
\n {++line;col=1;}
{keyword} {printf("[@%d,%d:%d='%s',<'keyword'>,%d:%d]\n",num++,col,col+yyleng,yytext,line,col);col+=yyleng;}
{identifier} {printf("[@%d,%d:%d='%s',<'identifier'>,%d:%d]\n",num++,col,col+yyleng,yytext,line,col);col+=yyleng;}
{integer_constant} {printf("[@%d,%d:%d='%s',<'integer_constant'>,%d:%d]\n",num++,col,col+yyleng,yytext,line,col);col+=yyleng;}
{floating_constant} {printf("[@%d,%d:%d='%s',<'floating_constant'>,%d:%d]\n",num++,col,col+yyleng,yytext,line,col);col+=yyleng;}
{character_constant} {printf("[@%d,%d:%d='%s',<'character_constant'>,%d:%d]\n",num++,col,col+yyleng,yytext,line,col);col+=yyleng;}
{string_literal} {printf("[@%d,%d:%d='%s',<'string_literal'>,%d:%d]\n",num++,col,col+yyleng,yytext,line,col);col+=yyleng;}
{bracket} {printf("[@%d,%d:%d='%s',<'bracket'>,%d:%d]\n",num++,col,col+yyleng,yytext,line,col);col+=yyleng;}
{opt} {printf("[@%d,%d:%d='%s',<'opt'>,%d:%d]\n",num++,col,col+yyleng,yytext,line,col);col+=yyleng;}
[ \t]+ {col+=4;}
. {col++;}%%
int main(){yyin=fopen("test.txt","r");yylex();return 0;
}
int yywrap(){return 1;
}

  将上述flex文件生成词法分析程序的命令:flex Scan.l
  生成一个名为lex.yy.c的词法分析程序。
  编译词法分析程序的命令:gcc lex.yy.c –lfl
  

测试代码

测试代码1:分析标识符,关键字,字符串

#include<stdio.h>
#include<stdlib.h>int main(){printf("Hello!\n");return 0;
}

测试代码2:增加更多的标识符,操作符

#include<stdio.h>
#include<stdlib.h>int main(){int a=9;double b=9.9;char c='9';if(a==9) a*=9;for(i=0;i<9;i++){b=b-1;}return 0;
}

  

实验结果

测试代码一:

测试代码二:


  在这个输出的token流中,每行为一个token,以@开头的数字表示token的序号,紧接着的xx:xx表示token文本对应的开始列和结束列,“=”后面给出了这个范围之内token的具体文本,“<>”之内表示token的类型,最后一个数字对xx:xx表示起始行和起始列。

利用Flex自动生成C语言词法分析器相关推荐

  1. nodejs html多语言切换,利用 nodejs 自动生成 Android 语言包实现应用内切换多语言的方案...

    Android 默认的多语言支持 在 Android 工程的 res 目录下,通过定义对应的语言文件夹名称就可以实现多语言支持 // 手动切换语言 Resources resources = getR ...

  2. Wix 安装部署教程(十六) -- 自动生成多语言文件

    Wix 安装部署教程(十六) -- 自动生成多语言文件 原文:Wix 安装部署教程(十六) -- 自动生成多语言文件 因为持续集成需要,所有项目编译完之后生成一个多语言的安装包.之前生成mst文件都是 ...

  3. 利用ApacheCXF自动生成webservice的客户端代码

    利用ApacheCXF自动生成webservice的客户端代码 一.环境准备 1.JDK环境 2.下载apache-cxf发布包,举例版本为3.2.14,解压发布包,设置CXF_HOME,并添加%CX ...

  4. php开发工程师名片,PHP编程:利用PHP自动生成印有用户信息的名片

    <PHP编程:利用PHP自动生成印有用户信息的名片>要点: 本文介绍了PHP编程:利用PHP自动生成印有用户信息的名片,希望对您有用.如果有疑问,可以联系我们. 前言 PHP教程无论是自己 ...

  5. c语言创建可视化窗口,一种基于可视化界面绘制图形自动生成C语言代码软件的设计与实现...

    第 35 卷第 9 期 计算机应用与软件 Vol. 35 No. 9 2018 年 9 月 Computer Applications and Software Sep. 2018 一种基于可视化界面 ...

  6. 【机器学习PAI实战】—— 玩转人工智能之利用GAN自动生成二次元头像

    前言 深度学习作为人工智能的重要手段,迎来了爆发,在NLP.CV.物联网.无人机等多个领域都发挥了非常重要的作用.最近几年,各种深度学习算法层出不穷, Generative Adverarial Ne ...

  7. 【机器学习PAI实战】—— 玩转人工智能之利用GAN自动生成二次元头像...

    模型训练与在线预测服务.推荐算法四部曲.机器学习PAI实战.更多精彩,尽在 开发者分会场 [机器学习PAI实战]-- 玩转人工智能之综述 [机器学习PAI实战]-- 玩转人工智能之商品价格预测 [机器 ...

  8. java编程猜数字大小 (要求利用随机数自动生成一个0--100内的随机数字)

    java编程猜数字(要求利用随机数自动生成一个0–100内的随机数字) public static void main(String[] args) {int num=(int)(Math.rando ...

  9. python乘法符号手写_利用Python自动生成小学生加减乘除口算考试题卷,不再为手写算术题烦恼!...

    还在为给孩子抄各种各样的口算题而烦恼?孩子上小学一年级之后,加减乘除的口算就要开始练习了,老师肯定会让家长出题.所以我们当家长的,要提前准备一下,就利用Python开发了一套自动生成小学生口算题的小应 ...

最新文章

  1. 阿里云E-HPC联合安世亚太、联科集团共建云超算生态
  2. mysql平台workb_MySQL分布式事务
  3. 百练OJ:1017:装箱问题
  4. 整理的常用JAVA开源库简介
  5. HP-UNIX操作系统root账号被锁定的两种解决方法
  6. MongoDB数据库基本操作笔记
  7. Android 功耗(5)----功耗调试
  8. windows下的安装与使用curl实现命令行访问Web网站
  9. Lego-美团点评接口自动化测试实践
  10. c++ string 末尾追加char字符
  11. 3D数学之矩阵的各种求逆
  12. 操作系统核心原理-3.进程原理(上):进程概要
  13. Gigapixel AI 6.0 for Mac(图片无损放大软件)
  14. 第十次课:Python函数(一)
  15. 数据结构C语言严蔚敏版(第二版)超详细笔记附带课后习题
  16. Axure RP 9.0 中继器增删改查实现[原型图]
  17. 从 0 到 1,开发一个智能问答机器人
  18. 使用GLAD加载OpenGL的库
  19. PyEcharts 直角坐标系图表之箱形图
  20. 按键精灵手机版 找图(Findpic)以及其与点击、runapp和找点的对比

热门文章

  1. MATLAB随机数产生方法
  2. ZYNQ下linux通过xdevcfg在线更新PL
  3. twincat不使用倍福控制器情况下的实时性测试
  4. 内部矩阵维度必须一致simulink_浅谈数仓模型(维度建模)
  5. 引领运动耳机新风尚、南卡携手世界冠军郭丹打造冠军品质
  6. PHP文件包含漏洞(利用phpinfo)
  7. java毕业生就业管理系统 高校毕业生就业服务平台 就业管理系统 高校就业统计系统 java就业管理系统毕设(源代码+数据库+调试运行+代码讲解)
  8. 08年,如何迈出职场成功第一步?
  9. 提问的智慧: 如何适当的提出问题。
  10. RStudio的语法结构