ILD

calc2
作者:Yuan Jianpeng 邮箱:yuanjp@hust.edu.cn
发布时间:2018-8-6 站点:Inside Linux Development

添加乘除以及括号支持


calc2.l

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    /* calculator #1 */
%{
    #include "y.tab.h"
    #include <stdlib.h>
    void yyerror(char *);
%}
 
%%
 
[a-z]       {
                yylval = *yytext - 'a';
                return VARIABLE;
                }
 
[0-9]+      {
                yylval = atoi(yytext);
                return INTEGER;
            }
 
[-+()=/*\n]     { return *yytext; }
 
[ \t]   ;       /* skip whitespace */
 
.               yyerror("Unknown character");
 
%%
 
int yywrap(void) {
    return 1;
}


calc2.y

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
%{
    #include <stdio.h>
    void yyerror(char *);
    int yylex(void);
 
    int sym[26];
%}
 
%token INTEGER VARIABLE
%left '+' '-'
%left '*' '/'
 
%%
 
program:
        program statement '\n'
        | /* NULL */
        ;
 
statement:
        expression                      { printf("%d\n", $1); }
        | VARIABLE '=' expression       { sym[$1] = $3; }
        ;
 
expression:
        INTEGER
        | VARIABLE                      { $$ = sym[$1]; }
        | expression '+' expression     { $$ = $1 + $3; }
        | expression '-' expression     { $$ = $1 - $3; }
        | expression '*' expression     { $$ = $1 * $3; }
        | expression '/' expression     { $$ = $1 / $3; }
        | '(' expression ')'            { $$ = $2; }
        ;
 
%%
 
void yyerror(char *s) {
    fprintf(stderr, "%s\n", s);
}
 
int main(void) {
    yyparse();
}


%left指定operator是left-associative。%right指定为right associative。列表中最后定义的有最高的优先级。


Makefile

1
2
3
4
5
6
7
all:
    bison -y -d calc2.y
    flex calc2.l
    gcc -o calc2 y.tab.c lex.yy.c
 
clean:
    rm -f *.yy.c *.tab.c *.tab.h calc2


运行:

1
2
3
4
5
$ ./calc2
1+2*3
7
(1+2) * 3
9


Copyright © linuxdev.cc 2017-2024. Some Rights Reserved.