解析器和扫描仪为x1 + x2 + ... + xn

时间:2014-02-19 16:34:24

标签: c visual-studio-2008 bison flex-lexer lexical-analysis

我正在尝试创建一个解析器扫描程序,它将输入一个文件,该文件包含这样的内容: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:我有一些关于它应该如何看的说明,这就是为什么它就是这样的。无论你能给我什么线索都会非常感激,因为我发现它很难理解互联网指南(尽管仍在努力)。

1 个答案:

答案 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。希望有所帮助!