Почему моя грамматика "уравнения" нарушает синтаксический анализатор? - PullRequest
0 голосов
/ 25 марта 2019

В настоящее время мой файл парсера выглядит следующим образом:

%{

#include <stdio.h>
#include <math.h>

int yylex();
void yyerror (const char *s);

%}

%union {
    long num;
    char* str;
}

%start line

%token print
%token exit_cmd

%token <str> identifier
%token <str> string
%token <num> number

%%

line: assignment            {;}
    | exit_stmt             {;}
    | print_stmt            {;}
    | line assignment       {;}
    | line exit_stmt        {;}
    | line print_stmt       {;}
    ;

assignment: identifier '=' number       {printf("Assigning var %s to value %d\n", $1, $3);}
          | identifier '=' string       {printf("Assigning var %s to value %s\n", $1, $3);}
          ;

exit_stmt: exit_cmd         {exit(0);}
         ;

print_stmt: print print_expr      {;}
          ;

print_expr: string          {printf("%s\n", $1);}
          | number          {printf("%d\n", $1);}
          ;

%%

int main(void)
{
    return yyparse();

}

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

Предоставление ввода: myvar = 3 дает вывод Assigning var myvar = 3 to value 3, как и ожидалось.Однако изменение кода для включения правила грамматики equation нарушает такие назначения.

Грамматика уравнения:

equation: number '+' number             {$$ = $1 + $3;}
    | number '-' number             {$$ = $1 - $3;}
    | number '*' number             {$$ = $1 * $3;}
    | number '/' number             {$$ = $1 / $3;}
    | number '^' number             {$$ = pow($1, $3);}
    | equation '+' number           {$$ = $1 + $3;}
    | equation '-' number           {$$ = $1 - $3;}
    | equation '*' number           {$$ = $1 * $3;}
    | equation '/' number           {$$ = $1 / $3;}
    | equation '^' number           {$$ = pow($1, $3);}
    ;

Также соответствующим образом изменяется грамматика назначения:

assignment: identifier '=' number       {printf("Assigning var %s to value %d\n", $1, $3);}
          | identifier '=' equation     {printf("Assigning var %s to value %d\n", $1, $3);}
          | identifier '=' string       {printf("Assigning var %s to value %s\n", $1, $3);}
          ;

И присвоение правилу equation типа num в первом разделе анализатора:

%type <num> equation

Предоставление того же ввода: var = 3 останавливает программу.

Я знаю, что это длинный вопрос, но может кто-нибудь объяснить, что здесь происходит?

Кроме того, вот лексер на случай, если вы захотите взглянуть.

1 Ответ

4 голосов
/ 25 марта 2019

Это не "заморозить программу".Программа просто ожидает большего ввода.

В вашей первой грамматике var = 3 - это полное утверждение, которое не может быть расширено.Но в вашей второй грамматике это может быть начало var = 3 + 4, например.Поэтому парсер должен прочитать другой токен после 3.Если вы хотите, чтобы входные строки заканчивались символом новой строки, вам нужно будет изменить сканер, чтобы он отправлял символ новой строки в качестве токена, а затем измените грамматику так, чтобы в конце каждого оператора ожидался токен новой строки.Если вы хотите, чтобы операторы были распределены по нескольким строкам, вам нужно знать об этом при вводе ввода.

Есть несколько проблем с вашей грамматикой, а также с вашим анализатором. (Flexнапример, не поддерживает не жадное повторение.) Пожалуйста, посмотрите примеры в руководствах для зубров и flex

...