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