Flex / Bison没有正确评估

时间:2014-02-25 02:30:08

标签: c++ c bison flex-lexer

由于某种原因,野牛不想做任何评估。所有文件的编译顺利进行,程序运行。当我输入表达式4+5并按回车键时,它会分别为4 + 5创建令牌。我甚至可以将一些printf放入野牛识别每个标记属性的地方,包括加号(43)。

但是程序从不评估此生产expr '+' term { $$ = $1 + $3; }。至少根据我的知识,它根本就没有被调用,即使是这个生产assign '\n' { printf("%d\n", $1); }也从未打印出价值。在^D退出后,它会触发void yyerror(const char *)

非常感谢您对此事的任何帮助。谢谢!

//FLEX
%{
    //#include <stdio.h>
    #include "y.tab.h"
%}

%option noyywrap

letter  [A-Za-z]
digit   [0-9]
space   [ \t]

var     {letter}
int     {digit}+
ws      {space}+

%%

{var}   { yylval = (int)yytext[0]; return VAR; }
{int}   { yylval = atoi(yytext); return CONST; }
{ws}    { }
.       { return (int)yytext[0]; }

%%

/* nothing */

//BISON
%{

//INCLUDE
//#include <ctype.h>

//DEFINE
#define YYDEBUG 1

//PROTOTYPE
void yyerror(const char *);
void print_welcome();
int get_val(int);
void set_val(int, int);

%}

%token CONST
%token VAR

%%

session
    : { print_welcome(); }
      eval
    ;

eval
    : eval line
    |
    ;

line
    : assign '\n'       { printf("%d\n", $1); }
    ;

assign
    : VAR '=' expr      { set_val($1, $3); $$ = $3; }
    | expr              { $$ = $1; }
    ;

expr
    : expr '+' term     { $$ = $1 + $3; }
    | expr '-' term     { $$ = $1 - $3; }
    | term              { $$ = $1; }
    ;

term
    : term '*' factor   { $$ = $1 * $3; }
    | term '/' factor   { $$ = $1 / $3; }
    | term '%' factor   { $$ = $1 % $3; }
    | factor            { $$ = $1; }
    ;

factor
    : '(' expr ')'      { $$ = $2; }
    | CONST             { $$ = $1; }
    | VAR               { $$ = get_val($1); }
    ;

%%

void yyerror(const char * s)
{
    fprintf(stderr, "%s\n", s);
}

void print_welcome()
{
    printf("Welcome to the Simple Expression Evaluator.\n");
    printf("Enter one expression per line, end with ^D\n\n");
}

static int val_tab[26];

int get_val(int var)
{
    return val_tab[var - 'A'];
}

void set_val(int var, int val)
{
    val_tab[var - 'A'] = val;
}

//MAIN

//PROTOTYPE
int yyparse();

int main()
{
    extern int yydebug;
    yydebug = 0;
    yyparse();
    return 0;
}

1 个答案:

答案 0 :(得分:3)

您的lex文件没有符合\n的任何规则,因为在lex / flex中,.匹配任何字符,但< / em> line-end。 lex(或flex)的默认规则会回显并忽略匹配的字符,因此\n会发生这种情况。由于解析器除非看到line令牌,否则将无法接受\n,因此最终会强制它向您显示语法错误。

所以你需要改变规则

.     { return (int)yytext[0]; }

.|\n  { return (int)yytext[0]; }

(我不会对演员int感到困扰,但它确实没有造成任何伤害,所以我把它留在了。)