Flex / Bison не оценивает должным образом

0

По той или иной причине зубр не хочет делать никаких оценок. Компиляция всех файлов идет гладко и программа запускается. Когда я вхожу в выражение 4+5 и нажимаю return, он создает токены для 4 + 5 соответственно. Я даже могу помещать некоторые printf в те места, где бизон распознает атрибуты каждого токена, включая плюс (43).

Однако программа никогда не оценивает этот expr '+' term { $$ = $1 + $3; } expr '+' term { $$ = $1 + $3; }. Он просто никогда не назывался, по крайней мере, до моего сведения, и даже если бы это было производство, assign '\n' { printf("%d\n", $1); } 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;
}
  • 0
    Включите отладку YACC, скомпилировав с параметром -DYYDEBUG = 1, а затем установив переменную оболочки env export YYDEBUG = 1 перед запуском программы. Он печатает очень читаемый вывод о сдвиге и сокращении операций.
  • 0
    Возвращает ли лексер '\ n'? Если нет, то ваше правило линии не сработает. Вы можете считать '\ n' пробелом и использовать ';' как конец выражения.
Показать ещё 3 комментария
Теги:
bison
flex-lexer

1 ответ

3
Лучший ответ

Ваш lex файл не имеет каких - либо правило, которое соответствует \n, потому что в lex/flex, . соответствует любому символу, кроме строки. Правило по умолчанию для эхо-сигналов lex (или flex) и в противном случае игнорирует согласованный символ, так что что происходит с \n. Поскольку анализатор не сможет принять line если не видит токен \n, он в конечном итоге будет вынужден представить вам синтаксическую ошибку.

Поэтому вам нужно изменить правило

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

в

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

(Я бы не стал беспокоиться о том, чтобы бросить int но это, конечно, не навредило, поэтому я его оставил.)

  • 0
    Что смешно, я отключился и пошел спать на ночь. Потом мне приснилось, что в этом и была проблема (спасибо, Саби). Я так сильно смеялся, когда увидел твой пост этим утром, иногда я могу быть настоящим идиотом. Спасибо за вашу помощь, я очень ценю это. Теперь все отлично работает. : D

Ещё вопросы

Сообщество Overcoder
Наверх
Меню