LEX & YACC - пробелы в выражениях - PullRequest
4 голосов
/ 16 февраля 2012

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

Вот мой файл lex (я опущу основной, который читает в файле):

%{

 #include "y.tab.h"
 #include "stdio.h"
 #include <stdlib.h>

%}
%%
(\/\*([^*]|(\*+([^*/]|[\r\n])))*\*+\/)+ {}
\/\/[^\n]*\n          {}
fd                    { return FD; }
[\r\t\n]+             {}
[ ]*                  {}
bk                    { return BK;}
setc                  {return SETC;}
[-+]?[0-9]+           { yylval = atoi(yytext); return NUMBER;}
fd[0-9]+              { }
rt                    {return RT;}
pink                  {return COLOR_TYPE;}
magenta               {return COLOR_TYPE; }
if                    {return IF; }
ifelse                {return IFELSE; }
\[                    {return LBRACKET; }
\]                    {return RBRACKET; }
\<                    {return LESS_THAN; }
\>                    {return GREATER_THAN; }
\+                    {return PLUS; }
\-                    {return MINUS; }
\/                    {return DIVIDE; }
\*                    {return MULT; }
\(                    {return LPAREN;}
\)                    {return RPAREN;}
\=                    {return EQ;}

%%

Вот часть моего файла yacc, которыйимеет дело с выражением:

expr    : NUMBER     { printf("EXPR-->NUMBER: %d\n", $1);}
   |expr PLUS expr   {$$ = $1 + $3; printf("EXPR-->expression PLUS expression: %d\n", $$);}
   |expr DIVIDE expr {$$ = $1 / $3; printf("EXPR-->expression DIVIDE expression %d\n", $$);}
   |expr MULT expr   {$$ = $1 * $3; printf("EXPR-->expression MULTIPLY expression %d\n", $$);}
   |expr MINUS expr  {$$ = $1 - $3; printf("EXPR-->expression MINUS expression %d\n", $$);}
   |COLOR_TYPE       {printf("EXPR-->COLOR\n");}
   ;

будет ли проблема в файле lex?

1 Ответ

6 голосов
/ 16 февраля 2012

Токенайзер (лексер) возвращает эти два парсера: 5 и +5. Который по вашей грамматике (и логически) недопустим.

Я думаю, вам было бы лучше изменить свой лексер и поднять правила для операторов. (Это означает, что, по крайней мере, выше правила, возвращающего NUMBER).

РЕДАКТИРОВАНИЕ: Подумав ( РЕДАКТИРОВАТЬ # 2: и более чем полезный комментарий Джерри Коффина), я предлагаю изменить лексическое правило для NUMBER на [0-9]+ , Чтобы синтаксический анализатор все еще принимал ввод, такой как «+123» или «-123», вы должны добавить это к вашей грамматике:

%left PLUS MINUS ...
%right UNARY

%%

expr   : number
       | expr PLUS expr
      ...
       ;

number : PLUS NUMBER %prec UNARY {$$ = $2}
       | MINUS NUMBER %prec UNARY {$$ = -$2}
       | NUMBER 
       ;

Это позволит унарное число + или - перед любым числом, но при этом операторы + и - будут иметь более высокий приоритет.

...