我试图理解编译器和编程语言是如何制作的。为此,我考虑创建一个简单的计算器,它只进行加法和减法。以下是我写的 Lex 和 Yacc 文件。
calc.yacc 文件:
%{
#include <stdio.h>
#include <stdlib.h>
extern int yylex();
void yyerror(char *);
%}
%union { int number; }
%start line
%token <number> NUM
%type <number> expression
%%
line: expression { printf("%d\n", $1); };
expression: expression '+' NUM { $$ = $1 + $3; };
expression: expression '-' NUM { $$ = $1 - $3; };
expression: NUM { $$ = $1; };
%%
void yyerror(char *s) {
fprintf(stderr, "%s", s);
exit(1);
}
int main() {
yyparse();
return 0;
}
calc.lex 文件:
%{
#include <stdio.h>
#include <stdlib.h>
#include "y.tab.h"
%}
%%
[0-9]+ {
yylval.number = atoi(yytext);
return NUM;
}
[-+] { return yytext[0]; }
[ \t\f\v\n] { ; }
%%
int yywrap() {
return 1;
}
它编译得很好但是当我运行它并键入2 + 4
之类的东西时,它会卡住并且不会打印出答案。有人可以解释一下原因吗?我的猜测是我的语法不正确(但我不知道如何)。
答案 0 :(得分:0)
我的想法与rici相同,并且适当地更改了样本:
档案%{
#include <stdio.h>
#include <stdlib.h>
#include "calc.y.h"
%}
%%
[0-9]+ {
yylval.number = atoi(yytext);
return NUM;
}
[-+] { return yytext[0]; }
"\n" { return EOL; }
[ \t\f\v\n] { ; }
%%
int yywrap() {
return 1;
}
:
calc.y
档案%{
#include <stdio.h>
#include <stdlib.h>
extern int yylex();
void yyerror(char *);
%}
%union { int number; }
%start input
%token EOL
%token <number> NUM
%type <number> expression
%%
input: line input | line
line: expression EOL { printf("%d\n", $1); };
expression: expression '+' NUM { $$ = $1 + $3; };
expression: expression '-' NUM { $$ = $1 - $3; };
expression: NUM { $$ = $1; };
%%
void yyerror(char *s) {
fprintf(stderr, "%s", s);
exit(1);
}
int main() {
yyparse();
return 0;
}
:
$ flex -o calc.l.c calc.l
$ bison -o calc.y.c -d calc.y
$ gcc -o calc calc.l.c calc.y.c
$ ./calc
2 + 4
6
2 - 4
-2
234 + 432
666
编译&amp;在Windows 10(64位)上的cygwin中测试:
#include
注意:
次要问题:根据构建命令,我必须更改生成的令牌表的EOL
。 (品味问题。)
我在lex源代码中以及解析器的line
规则中引入了input
标记。
测试时我发现第二个输入在语法错误中每次都结束。我需要一段时间,直到我认识到语法实际上现在只限于接受一行。因此,我在解析器源中插入了递归?>
<script type="text/javascript">
$(document).ready(function() {
$("#menu2").click(function(event) {
event.preventDefault();
swal("Many thanks to everyone for making me a better programmer.!", "Message", "success");
})
});
</script>
<?php
规则。