因为是非计算机本科,所以没有学编译原理,进来想补补课,于是买了本《自制编程语言》,里面介绍了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
来看看执行效果吧
还不错哦~~