《自制编程语言》笔记:使用yacc与lex制作简单计算器

1、代码

  1.1)test.l

  1.2)test.y

  1.3)Makefile  (因为是在linux环境下,所以使用了Makefile)

2、编译与运行

  2.1)编译

  2.2)运行


1、代码(也可以在我的百度网盘下载:http://pan.baidu.com/s/1o65k7v8

  1.1)lex文件 test.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 "
"   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 [ 	] ;
24 .  {
25     fprintf(stderr, "lexical error.
");
26     exit(1);
27 }
28 %%

  1.2)yacc文件text.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
> ", $1);
22         fflush(stdout);
23     }   
24 expression
25     : term
26     | expression ADD term
27     {
28         $$ = $1 + $3;
29     }
30     | expression SUB term
31     {
32         $$ = $1 - $3;
33     }
34     ;
35 term 
36     : primary_expression
37     | term MUL primary_expression
38     {
39         $$ = $1 * $3;
40     }
41     | term DIV primary_expression
42     {
43         $$ = $1 / $3;
44     }
45     ;
46 primary_expression 
47     : DOUBLE_LITERAL
48     ;
49 %%
50 int
51 yyerror(char * str)
52 {
53     extern char * yytext;
54     fprintf(stderr, "parser error near %s
", yytext);
55     return 0;
56 }
57 
58 int main(void)
59 {
60     extern int yyparse(void);
61     extern FILE * yyin;
62 
63     printf("> ");
64     fflush(stdout);
65     yyin = stdin;
66     if (yyparse()) {
67         fprintf(stderr, "Error ! Error ! Error !
");
68         exit(1);
69     }
70 }

  1.3)Makefile文件(其实不用Makefile的,我这里为了每次编译和清除的时候方面才使用的,以下的命令可以分三步手动执行,原著里面就是手动执行的)

1 .PHONY : dummy
2 
3 all : dummy
4     yacc -dv test.y
5     lex test.l
6     gcc -o test lex.yy.c y.tab.c
7 
8 clean : dummy
9     rm -rf lex.yy.c test y.output y.tab.c y.tab.h

2、编译与运行

  2.1)编译

1 $ make
2 yacc -dv test.y
3 lex test.l
4 gcc -o test lex.yy.c y.tab.c

  2.2)运行

1 $ ls
2 lex.yy.c  Makefile  readme.txt  test  test.l  test.y  y.output  y.tab.c  y.tab.h
3 $ ./test 
4 > 1 + 2 * 3-4+2*3/7
5 >>3.857143
6 > q
7 lexical error.

来源:《自制编程语言》第二章

百度百科:http://baike.baidu.com/link?url=WC3BGKHo7gMEuPbxrX8Wsa6-KD69HLbRjd6TnmGPZNcq9j7xtgZxXh7RPufn2ISHIwW6A8Zri6Qt_5xViF9Vi_

豆瓣:http://book.douban.com/subject/25735333/

原文地址:https://www.cnblogs.com/fengbohello/p/4634073.html