编译原理学习一:flex,bsion工具使用
先尝试用它来做一个计算器(内容来自于自制编程语言——前桥和弥)
一、准备工作
关于flex, bsion工具,建议还是linux平台安装使用比较方便,我在windows下尝试过,太麻烦。
在ubuntu下安装很简单,只要执行下列语句即可:
sudo apt-get install flex bison flex -h bison -h
没有报错就说明安装成功。
二、词法分析部分
创建mycalc.l
1 %{ 2 #include <stdio.h> 3 #include "y.tab.h" 4 5 int 6 yywrap(void) 7 { 8 return 1; 9 } 10 %} 11 %% 12 "+" return ADD; 13 "-" return SUB; 14 "*" return MUL; 15 "/" return DIV; 16 "\n" return CR; 17 ([1-9][0-9]*)|0|([0-9]+\.[0-9]+) { 18 double temp; 19 sscanf(yytext, "%lf", &temp); 20 yylval.double_value = temp; 21 return DOUBLE_LITERAL; 22 } 23 [ \t] 24 . { 25 fprintf(stderr, "lexical error.\n"); 26 exit(1); 27 } 28 %%
三、语法分析部分
创建mycalc.y
1 %{ 2 #include <stdio.h> 3 #include <stdlib.h> 4 #define YYDEBUG 1 5 %} 6 %union { 7 int int_value; 8 double double_value; 9 } 10 %token <double_value> DOUBLE_LITERAL 11 %token ADD SUB MUL DIV CR 12 %type <double_value> expression term primary_expression 13 %% 14 line_list 15 : line 16 | line_list line 17 ; 18 line 19 : expression CR 20 { 21 printf(">>%lf\n", $1); 22 } 23 expression 24 : term 25 | expression ADD term 26 { 27 $$ = $1 + $3; 28 } 29 | expression SUB term 30 { 31 $$ = $1 - $3; 32 } 33 ; 34 term 35 : primary_expression 36 | term MUL primary_expression 37 { 38 $$ = $1 * $3; 39 } 40 | term DIV primary_expression 41 { 42 $$ = $1 / $3; 43 } 44 primary_expression 45 : DOUBLE_LITERAL 46 ; 47 %% 48 int 49 yyerror(char const *str) 50 { 51 extern char *yytext; 52 fprintf(stderr, "parser error near %s\n", yytext); 53 return 0; 54 } 55 56 int main(void) 57 { 58 extern int yyparse(void); 59 extern FILE *yyin; 60 61 yyin = stdin; 62 if(yyparse()) { 63 fprintf(stderr, "Error ! Error ! Error !\n"); 64 exit(1); 65 } 66 }
四、生成执行文件
bison --yacc -dv mycalc.y flex mycalc.y gcc -o mycalc y.tab.c lex.yy.c
执行上述语句后,可以在目录中看到mycalc程序。
五、测试
./mycalc 1+3*5 >>16 q lexical error.