小白说编译原理-2-lex基本用法
2016-04-23 09:55
405 查看
lex词法分析器
概述
1,使用lex语言书写一套正规表达式的规则,命名为lex.l2,由lex编译器负责将lex.l编译为lex.h和lex.cpp,这两个文件包含了lex定义的规则
3,再使用标准的c++编译器即可以将lex.cpp编译生成可执行程序lex.exe
4,lex.exe识别输入流,并将其转换为字符序列,并执行相应的操作(在lex.l中定义)
lex样例
%{ /***/ %} // lexical analyser name %name lexer %% [ \t]+ {printf(" ");} \n|. {printf("%s", yytext);} %% int main() { //create a lexer, and call the lex function. //it will read from stdin and parser the tokens. YYLEXERNAME lexer; if(lexer.yycreate()){ lexer.yylex(); } }
简单的语法结构
声明段:%{ c++语言代码,一般为头文件包含,以及变量声明,定义。 注意:代码会被原样copy到生成的代码文件中。 %} 正规定义
规则段:
%% 用户定义的转换规则 P1 {action} P1表示正规表达式,action为相应的执行动作。 %%
子程序段:
主要包含用户子程序代码,代码会被原样copy到生成的代码文件中。
解析说明例子
%name lexer这是说明词法分析器的类名字为lexer,最后生成的代码中会有 #define YYLEXERNAME lexer。
[ \t]+ {printf(” “);}
前面是表达式,后面{}中是进行的动作。 [ \t]+表示连续的空白字符(空格,tab), 进行的语义动作是打印一个空格。
\n|. {printf(“%s”, yytext);}
其他任意字符,原样打印。因为.无法表达\n这样的字符,所以使用|的或操作。
功能说明
将连续的空格或者tab压缩为一个空格,其他字符原样输出。
lex样例2,解析token
%{ #include <iostream> using namespace std; enum{ LT, EQ, GT, IF, ELSE, ID, NUMBER, PLUS, MINUS, TIMES, OVER, INT, DOUBLE,CHAR }; const char* tokenStr[] = {"LT", "EQ", "GT", "IF", "ELSE", "ID", "NUMBER", "PLUS", "MINUS", "TIMES", "OVER", "INT", "DOUBLE","CHAR" }; static void print_token(int token, char* lex); %} %name lexer delim [ \t\n] ws {delim}+ letter [a-zA-Z] digit [0-9] id {letter}({letter}|{digit})* /* can support 12.34 */ number {digit}+(\.{digit}+)? %% {ws} {/* do nothing */} "int" {print_token(INT, yytext);} "double" {print_token(DOUBLE, yytext);} "char" {print_token(CHAR, yytext);} "+" {print_token(PLUS, yytext); } "-" {print_token(MINUS, yytext);} "*" {print_token(TIMES, yytext);} "/" {print_token(OVER, yytext); } {id} {print_token(ID, yytext);} {number} {print_token(NUMBER, yytext);} %% static void print_token(int token, char* lex) { cout<<"token:" << tokenStr[token]<<" "<<"lex:"<<lex<<endl; } int main() { //create a lexer, and call the lex function. //it will read from stdin and parser the tokens. YYLEXERNAME lexer; if(lexer.yycreate()){ lexer.yylex(); } }
样例2说明
最前面的%{ … %}内的为变量以及函数声明部分%name lexer 定义词法分析器的名字
delim [ \t\n] 这些是正规的定义,通过递归的定义可以定义更复杂的正规式,例如id和number的定义
%% … %% 正规表达式与执行的动作的绑定
最后的函数实现代码为整个驱动程序,它读取用户输入,并解析token,执行action
下节内容
yacc语法程序,能够实现一个简单的四则运算。本人lpstudy,转载请注明出处: http://blog.csdn.net/lpstudy/article/details/51224869
相关文章推荐
- 20160423
- DataGridView列标题(列标头)不能居中的解决方法
- Mybatis最入门---动态查询(choose,when,otherwise)
- win7_64bits下QT试用openCV库(1)
- bzoj 1845: [Cqoi2005] 三角形面积并(计算几何)
- 滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(4月23日)
- storm 备忘
- bzoj 1036: [ZJOI2008]树的统计Count(树链剖分 点权)
- IntelliJ IDEA 使用心得与常用快捷键
- nodejs基于express4+mysql+express-controller的mvc框架
- 面试需要啥?
- 第九周项目1-深复制体验(3)
- 阿里云Centos7安装LNMP+wordpress
- ubuntu14.04与win7相互共享
- ARM 指令集版本和ARM 版本
- SAP MM 用户不希望采购订单一旦Release就自动打印输出,如何控制?
- 1013 A strange lift
- codevs1051单词接龙(栈)
- [找规律 递归子问题 || 数位DP] BZOJ 4513 [Sdoi2016]储能表
- CentOs 7下vim安装YouCompleteMe插件