初步学习lex和yacc
2015-09-24 17:32
330 查看
因为是非计算机本科,所以没有学编译原理,进来想补补课,于是买了本《自制编程语言》,里面介绍了lex和yacc工具,于是装起来试了下。
原来用工具来解析字符串还是挺方便的,以前知道正则以后,就觉得这东西很好,现在有了lex和yacc,把正则能做的事情又放大了,能够做更丰富的事情。
例如,写一个简单的把字符串里的数字相加,其他忽略的程序(说是简单是指功能,其实调通很不简单,哈哈,特别是把%type写成了%token的笔误后,纠结了很久)
下面贴上代码
test.l
%{
#include <stdio.h>
#include "y.tab.h"
int
yywrap(void)
{ return 1; }
%}
%%
"\n" return CR;
[0-9]+ {
int temp;
sscanf(yytext, "%d", &temp);
yylval.int_value = temp;
return A;
}
[ \t] ;
. {
//other words
yylval.int_value = 0;
return ERR;
}
%%
test.y
%{
#include <stdio.h>
#include <stdlib.h>
%}
%union {
int int_value;
}
%token <int_value> A B
%token CR ERR
//!!this is %type!!
%type <int_value> expression other
%%
line_list : line | line_list line;
line : expression CR {
printf("%d\n", $1);
} | CR {
printf("exit.\n");
exit(0);
};
expression : A | other | expression A {
$$ = $1 + $2;
} | expression other {
$$ = $1 + $2;
};
other: ERR {
printf(".");
};
%%
int
yyerror(char const *str) {
extern char *yytext;
fprintf(stderr, "parser error near %s\n", yytext);
return 0;
}
int main(void) {
extern int yyparse(void);
extern FILE *yyin;
yyin = stdin;
if (yyparse()) {
fprintf(stderr, "Error ! Error ! Error !\n");
exit(1);
}
}
然后利用lex和yacc来生成一个可执行文件
yacc -dv test.y
lex test.l
cc *.c
来看看执行效果吧
还不错哦~~
原来用工具来解析字符串还是挺方便的,以前知道正则以后,就觉得这东西很好,现在有了lex和yacc,把正则能做的事情又放大了,能够做更丰富的事情。
例如,写一个简单的把字符串里的数字相加,其他忽略的程序(说是简单是指功能,其实调通很不简单,哈哈,特别是把%type写成了%token的笔误后,纠结了很久)
下面贴上代码
test.l
%{
#include <stdio.h>
#include "y.tab.h"
int
yywrap(void)
{ return 1; }
%}
%%
"\n" return CR;
[0-9]+ {
int temp;
sscanf(yytext, "%d", &temp);
yylval.int_value = temp;
return A;
}
[ \t] ;
. {
//other words
yylval.int_value = 0;
return ERR;
}
%%
test.y
%{
#include <stdio.h>
#include <stdlib.h>
%}
%union {
int int_value;
}
%token <int_value> A B
%token CR ERR
//!!this is %type!!
%type <int_value> expression other
%%
line_list : line | line_list line;
line : expression CR {
printf("%d\n", $1);
} | CR {
printf("exit.\n");
exit(0);
};
expression : A | other | expression A {
$$ = $1 + $2;
} | expression other {
$$ = $1 + $2;
};
other: ERR {
printf(".");
};
%%
int
yyerror(char const *str) {
extern char *yytext;
fprintf(stderr, "parser error near %s\n", yytext);
return 0;
}
int main(void) {
extern int yyparse(void);
extern FILE *yyin;
yyin = stdin;
if (yyparse()) {
fprintf(stderr, "Error ! Error ! Error !\n");
exit(1);
}
}
然后利用lex和yacc来生成一个可执行文件
yacc -dv test.y
lex test.l
cc *.c
来看看执行效果吧
还不错哦~~
相关文章推荐
- POJ 1273 Drainage Ditches(最大流模板)
- Timer与TimerTask相关
- [9-15]Sed文本处理――高级用法
- pushMeBaby,github链接
- 整理的页面切换效果,项目源码。请大家收藏!
- 图像处理顶级期刊
- Android ant自动打包 crunch 报错
- ☆第二次作业
- 表单提交验证
- Guava Cache 实现详解
- Autolayout 基础
- 数字可以为正数或负数(可以含有小数点) java
- 传感器
- unix/linux编程实践教程---sscanf函数的用法
- upload4j安全、高效、易用的java http文件上传框架
- c pointer
- android 事件总线 -- Otto(三) ThreadEnforcer
- 随机数生成_srand/random
- 自定义安装linux/Ubuntu版本操作系统/自定义磁盘分区
- Android release版关闭日志logcat