2014-02-19 132 views
2

我想创建一个解析器 - 扫描仪将得到作为输入文件哪个文件有这样的东西里面:5 + 23 + ..... + 3;,我希望它打印结果屏幕上。解析器和扫描仪为x1 + x2 + ... + xn

我觉得有点难以理解$$ = $1 +...的工作方式,以及这些$1,$2与令牌是如何连接的。如果有人能向我解释那部分,我会非常感激。

我的代码到目前为止是这样的:

法代码:

%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:我已经在它应该如何看一些指令所以这就是为什么它是像那样。无论你能给我什么线索都会非常感激,因为我发现它很难理解互联网指南(尽管如此)。

回答

2

我不想太深入flex和野牛,所以我尽量简单地解释它。

$$罐解释为语法规则的返回值,一旦规则被finnished由解析器的$$值将通过给予(降低)。

因此,例如,规则:

addition : NUMBER PLUS NUMBER { } 

卷曲手镯的内部被称为操作规则。 $1 $2 $3 ...表示规则的第一个,第二个和第三个参数。

这意味着:

$1 = NUMBER 
$2 = PLUS 
$3 = NUMBER 

如果你想将号码添加到你写这样的事情在你的行动规则,对方号码:

addition : NUMBER PLUS NUMBER { printf("%d",$1+$3);} 

词法分析器是有点像解析器的子例程,解析器请求下一个符号,flex会扫描下一个符号的输入并将其传递给野牛。

有些事情要提到:解析器不知道数字内部是什么,他只是得到符号 NUMBER。为什么你需要像这样在你的Flex /野牛这就是:

柔性文件:

[0-9]+ { yylval.val = atoi(yytext); return NUMBER; } 

野牛:

%union { 
int val; 
}; 
%token <val> NUMBER 

了一个号码符号进行扫描,弯曲它的值写入瓦尔因此野牛可以访问它。

为了更好地理解发生了什么,我建议您在每个语法规则中都做一些printf。希望有所帮助!

+0

非常感谢您的回答...把它作为指导,我会尝试一些事情。如果你想回答的话,还有两个简单的问题。例如:NUMBER PLUS NUMBER printf工程,但是当我把这个{$$ = $ 1 + $ 3;}解析器抛出错误(我想做这样的事情来得到结果)。第二,除了声明终端(例如%token NUMBER)我是否还必须声明非终端来实现我的目标? –

+0

这里是一个flex和野牛计算器的例子。试着复制这个例子,并找出它的工作原理。如果你仍然有问题,你可以再问我一次:-) http://www.usna.edu/Users/cs/lmcdowel/courses/si413/F10/labs/L04/calc1/ex1.html – Amazonasmann

+0

对于你的语法规则,你需要做这样的事情:%type addition_list addition – Amazonasmann