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
%{
#include <stdio.h>
#include "y.tab.h" int
yywrap(void)
{
return ;
}
%}
%%
"+" return ADD;
"-" return SUB;
"*" return MUL;
"/" return DIV;
"\n" return CR;
([-][-]*)||([-]+\.[-]*) {
double temp;
sscanf(yytext, "%lf", &temp);
yylval.double_value = temp;
return DOUBLE_LITERAL;
}
[ \t] ;
. {
fprintf(stderr, "lexical error.\n");
exit();
}
%%
1.2)yacc文件text.y
%{
#include <stdio.h>
#include <stdlib.h>
#define YYDEBUG 1
%}
%union {
int int_value;
double double_value;
}
%token <double_value> DOUBLE_LITERAL
%token ADD SUB MUL DIV CR
%type <double_value> expression term primary_expression
%%
line_list
: line
| line_list line
;
line
: expression CR
{
printf(">>%lf\n> ", $);
fflush(stdout);
}
expression
: term
| expression ADD term
{
$$ = $ + $;
}
| expression SUB term
{
$$ = $ - $;
}
;
term
: primary_expression
| term MUL primary_expression
{
$$ = $ * $;
}
| term DIV primary_expression
{
$$ = $ / $;
}
;
primary_expression
: DOUBLE_LITERAL
;
%%
int
yyerror(char * str)
{
extern char * yytext;
fprintf(stderr, "parser error near %s\n", yytext);
return ;
} int main(void)
{
extern int yyparse(void);
extern FILE * yyin; printf("> ");
fflush(stdout);
yyin = stdin;
if (yyparse()) {
fprintf(stderr, "Error ! Error ! Error !\n");
exit();
}
}
1.3)Makefile文件(其实不用Makefile的,我这里为了每次编译和清除的时候方面才使用的,以下的命令可以分三步手动执行,原著里面就是手动执行的)
.PHONY : dummy all : dummy
yacc -dv test.y
lex test.l
gcc -o test lex.yy.c y.tab.c clean : dummy
rm -rf lex.yy.c test y.output y.tab.c y.tab.h
2、编译与运行
2.1)编译
$ make
yacc -dv test.y
lex test.l
gcc -o test lex.yy.c y.tab.c
2.2)运行
$ ls
lex.yy.c Makefile readme.txt test test.l test.y y.output y.tab.c y.tab.h
$ ./test
> + * -+*/
>>3.857143
> q
lexical error.
来源:《自制编程语言》第二章