我正在尝试创建一个解析器扫描程序,它将输入一个文件,该文件包含这样的内容:5 + 23 + ..... + 3;
我想让它在屏幕上打印结果。
我发现有点难以理解$$ = $1 +...
的工作原理以及这些$1
,$2
如何与令牌相关联。如果有人能解释我那部分我会非常感激。
我的代码到现在为止:
lex代码:
%option noyywrap
%%
\+ //{ yylval.p = yytext[0]; return PLUS; }
; //{ yylval.q = yytext[0]; return Q_MARK; }
0|([-+]?(([1-9][0-9]*)|(0\.[0-9]+)|([1-9][0-9]*\.[0-9]+))) { yylval.d = atof(yytext); return NUMBER; }
%%
flex代码:
%defines
%{
#include <stdio.h>
#include <stdlib.h>
%}
%union {
double d;
}
%token <d> NUMBER //some number
%token PLUS // +
%token Q_MARK // ;
%start addition_list
%%
addition_list : addition Q_MARK {}
| addition_list addition Q_MARK {}
;
addition : NUMBER PLUS NUMBER { }
| addition PLUS NUMBER { }
;
%%
int yyerror(char *message)
{
return 0;
}
void main()
{
yyparse();
}
ps:我有一些关于它应该如何看的说明,这就是为什么它就是这样的。无论你能给我什么线索都会非常感激,因为我发现它很难理解互联网指南(尽管仍在努力)。
答案 0 :(得分:2)
我不想深入研究flex和bison,所以我尽可能简单地解释它。
一旦解析器完成规则(减少),$$
可以被解释为语法规则的返回值,$$
值将被给出。{1}}可以解释为语法规则的返回值。
例如,规则:
addition : NUMBER PLUS NUMBER { }
花型手镯的内部称为动作规则。 $1 $2 $3
...代表规则的第一,第二和第三个参数。
这意味着:
$1 = NUMBER
$2 = PLUS
$3 = NUMBER
如果您想将NUMBER添加到其他NUMBER,您必须在操作规则中写下这样的内容:
addition : NUMBER PLUS NUMBER { printf("%d",$1+$3);}
Lexer类似于解析器的子程序,解析器请求下一个符号,flex会扫描下一个符号的输入并将其传递给bison。
值得一提的是:解析器不知道数字内部是什么,他只是得到符号 NUMBER。这就是你在flex / bison中需要这样的东西的原因:
flex文件:
[0-9]+ { yylval.val = atoi(yytext); return NUMBER; }
野牛:
%union {
int val;
};
%token <val> NUMBER
一旦扫描了NUMBER符号,flex会将其值写入val变量,以便bison可以访问它。
为了更好地了解会发生什么,我建议您在每个语法规则中执行一些printf。希望有所帮助!