2013-05-02 3 views
0

Мой текущий закон файл выглядит следующим образом:Flex: Синтаксическая ошибка при добавлении нового правила

%{ 
#include "foo.h" 
void rem_as(char* string); 
%} 

DIGIT  [0-9] 
LITTERAL  [a-zA-Z] 
SEP   [_-]|["."]|["\\"][ ] 
FILE_NAME ({DIGIT}|{LITTERAL}|{SEP})* 
PATH   ({FILE_NAME}"/"{FILE_NAME})*|({FILE_NAME}) 

%% 

"move"  {return MOVE;} 
"mv"   {return MOVE;} 
">"   {return R_STDOUT;} 
"2>"   {return R_STDERR;} 
"<"   {return R_STDIN;} 
"|"   {return PIPE;} 
"&"   {return AND;} 
"="   {return EQUAL_SIGN;} 
"-"?{DIGIT}+ {yylval.integer = atoi(yytext); return NUM;} 
{PATH}  {rem_as(yytext); sscanf(yytext,"%[^\n]",yylval.string); return FILENAME;} 
\n   {return LINEBREAK;} 
. ; 

%% 

Это работает очень хорошо.
Например, благодаря этой грамматике

Move: MOVE FILENAME FILENAME { move($2, $3); } 
    ; 

я могу делать такие вещи, как move a b.


Теперь моя проблема:

После добавления этого к моему ЛЕКС файл

VAR_NAME  [a-zA-Z][a-zA-Z0-9_-]* 

... 

{VAR_NAME} {return VAR_NAME;} // declared before the "=" rule 

Мои предыдущие правила испортиться, особенно FILENAME, которые теперь должны обязательно содержать символ '/'.

Например, с этой грамматикой:

VarDecl: VAR_NAME EQUAL_SIGN FILENAME { puts("foo"); } 
     ; 

a=b/ работа в то время как a=b бросает синтаксическую ошибку.

Любое представление о причинах проблемы?
Спасибо.

ответ

2

Порядок, в котором вы указываете правила lex, b соответствует VAR_NAME, поэтому токен VAR_NAME испускается, даже если он пытается сопоставить PATH, поэтому вы получаете правило VAR_NAME EQUAL_SIGN VAR_NAME, которое является недопустимым.

Простое решение - сделать PATH правилом в грамматике, а не в ваших лексических материалах.

PATH: VAR_NAME | FILE_NAME | VAR_NAME SLASH PATH | FILE_NAME SLASH PATH

добавление просто/как токен в файл lex.

+0

Решение, которое я выбрал, это использовать токен для 'var =', не имея никакой двусмысленности и не меняя моего кода. Ваш ответ заставил меня понять проблему, поэтому спасибо. –

Смежные вопросы