Получение предупреждения: правило не может быть сопоставлено

#bison #flex-lexer #lexical-analysis

Вопрос:

Поэтому я пытаюсь сделать лексический синтаксический анализ, используя гибкий код с небольшим количеством Зубра.Я продолжаю получать предупреждения о своих правилах, которые не могут быть сопоставлены, и я не могу найти никакой ошибки.Я также искал,что означает это предупреждение, но, думаю, я больше не объявлял подобное правило.Таким образом, я не думаю, что какое-либо другое правило превосходит другие правила и не может быть согласовано.Я продолжаю получать ошибку из строки 83,которая является {ЗАПЯТАЯ} {возвращаемая ЗАПЯТАЯ;}, до конца моего кода, и я не знаю, почему.Есть какие-нибудь идеи?

 WHITESPACE   [ t]
INTDEC   [0]|([1-9][0-9]*)
INTHEX   0[xX][0-9A-F] 
INTOCTAL   0[0-7] 
VARIABLE   [A-Za-z][a-zA-Z0-9_] 
COMMA   ","
INT   "int"
FLOAT   "float"
DOUBLE   "double"
VOID   "void"
LONG   "long"
SHORT   "short"
BREAK   "break"
RETURN   "return"
LEKTIKA   "(\[n"\]|[^"\n])*"
COMMENTS   "//".*
REAL   ([0][.][0-9] )|([1-9][0-9]*[.][0-9] )
EXP   ([0-9] |{REAL})[Ee]-?[0-9] 
UNKNOWN_TOKEN   [^ tn]*
NEWLINE   n
LESS_THAN   [<]
GREATER_THAN   [>]
GREATER_OR_EQUAL_TO   [>=]
LESS_OR_EQUAL_TO   [<=]
NOT_EQUAL_TO   [=!]
EQUAL   [==]
DIVIDE   [/]
MULTIPLY   [*]
MODULO   [%]
PLUS   [ ]
MINUS   [-]
PLUS_ASSIGN   [ =]
MINUS_ASSIGN   [-=]
MULT_ASSIGN   [*=]
DIV_ASSIGN   [/=]
LOGICAL_AND   [amp;amp;]
LOGICAL_OR   [||]
INCREMENT   [  ]
DECREMENT   [--]
ALL_OPERATORS   [{LESS_THAN}{GREATER_THAN}{GREATER_OR_EQUAL_TO}{LESS_OR_EQUAL_TO}{NOT_EQUAL_TO}{EQUAL}{DIVIDE}{MULTIPLY}{MODULO}{PLUS}{MINUS}{PLUS_ASSIGN}{MINUS_ASSIGN}{MULT_ASSIGN}{DIV_ASSIGN}   {LOGICAL_AND}{LOGICAL_OR}{INCREMENT}{DECREMENT}]
SCAN   scan[[(][{VARIABLE}][)];
LEN   len[(][{VARIABLE}|{LEKTIKA}|{INTDEC}|{REAL}|{EXP}]*[)];
CMP   cmp[(][{VARIABLE}|{LEKTIKA}|{INTDEC}|{REAL}|{EXP},]*[)];
PRINT   print[(][{VARIABLE}|{LEKTIKA}|{INTDEC}|{REAL}|{EXP}]*[)];
FUNCTION_NAME   {VARIABLE}
FUNCTION   [func] s[{FUNCTION_NAME}] s[(] [{INT}|{FLOAT}|{DOUBLE}s [{VARIABLE}],s]*[)]
CALL_FUNC   [{FUNCTION_NAME}][(][{INTEDEC}|{INTHEX}|{INOCTAL}|{REAL}][)];
ARRAY_NAME   [{VARIABLE}]
ARRAY_CON   [[][{INTDEC}|{VARIABLE}|{VARIABLE}|{LEKTIKA},s]*
ARRAY   [{ARRAY_NAME}]s[=]s[[][{INTDEC}|{VARIABLE}|{VARIABLE}|{LEKTIKA},]*[]];
DEC_INT   {INT}[{VARIABLE}];
DEC_FLOAT   {FLOAT}[{VARIABLE}];
DEC_DOUBLE   {DOUBLE}[{VARIABLE}];
COMPARISONS   [{VARIABLE}]s[{LESS_THAN}|{GREATER_THAN}|{GREATER_OR_EQUAL_TO}|        {LESS_OR_EQUAL_TO}|{NOT_EQUAL_TO}|{EQUAL}]s[{VARIABLE}]
DEC_VAR   [{DEC_INT}|{DEC_FLOAT}|{DEC_DOUBLE}];
VAR_ASSIGN   [{VARIABLE}|{ARRAY_NAME},s]*s[=]s[{INT}|{FLOAT}|{DOUBLE}|{ARRAY_CON},s]*;



%%
{WHITESPACE}    {}
{COMMENTS}      {}
{INTDEC}        {return INTDEC;}
{INTHEX}        {return INTHEX;}
{INTOCTAL}      {return INTOCTAL;}
{REAL}          {return REAL;}
{EXP}           {return EXP;}
{LEKTIKA}       {return LEKTIKA;}
{VARIABLE}      {return VARIABLE;}
{NEWLINE}       {return NEWLINE;}
{UNKNOWN_TOKEN} {return UNKNOWN_TOKEN;}
{COMMA}    {return COMMA;}
{INT}    {return INT;}
{FLOAT}    {return FLOAT;}
{DOUBLE}    {return DOUBLE;}
{VOID}    {return VOID;}
{LONG}    {return LONG;}
{SHORT}    {return SHORT;}
{BREAK}    {return BREAK;}
{RETURN}    {return RETURN;}
{LESS_THAN}    {return LESS_THAN;}
{GREATER_THAN}    {return GREATER_THAN;}
{GREATER_OR_EQUAL_TO}    {return GREATER_OR_EQUAL_TO;}
{LESS_OR_EQUAL_TO}    {return LESS_OR_EQUAL_TO;}
{NOT_EQUAL_TO}    {return NOT_EQUAL_TO;}
{EQUAL}    {return EQUAL;}
{DIVIDE}    {return DIVIDE;}
{MULTIPLY}    {return MULTIPLY;}
{MODULO}    {return MODULO;}
{PLUS}    {return PLUS;}
{MINUS}    {return MINUS;}
{PLUS_ASSIGN}    {return PLUS_ASSIGN;}
{MINUS_ASSIGN}    {return MINUS_ASSIGN;}
{MULT_ASSIGN}    {return MULT_ASSIGN;}
{DIV_ASSIGN}    {return DIV_ASSIGN;}
{LOGICAL_AND}    {return LOGICAL_AND;}
{LOGICAL_OR}    {return LOGICAL_OR;}
{INCREMENT}    {return INCREMENT;}
{DECREMENT}    {return DECREMENT;}
{ALL_OPERATORS}    {return ALL_OPERATORS;}
{SCAN}    {return SCAN;}
{LEN}    {return LEN;}
{CMP}    {return CMP;}
{PRINT}    {return PRINT;}
{FUNCTION_NAME}    {return FUNCTION_NAME;}
{FUNCTION}    {return FUNCTION;}
{CALL_FUNC}    {return CALL_FUNC;}
{ARRAY_NAME}    {return ARRAY_NAME;}
{ARRAY_CON}    {return ARRAY_CON;}
{ARRAY}    {return ARRAY;}
{DEC_INT}    {return DEC_INT;}
{DEC_FLOAT}    {return DEC_FLOAT;}
{DEC_DOUBLE}    {return DEC_DOUBLE;}
{COMPARISONS}    {return COMPARISONS;}
{DEC_VAR}    {return DEC_VAR;}
{VAR_ASSIGN}    {return VAR_ASSIGN;}
 

Ответ №1:

В ваших правилах {UNKNOWN_TOKEN} это появляется очень рано. Поскольку он соответствует любому маркеру любой длины, не содержащему пробелов, он будет соответствовать тем же маркерам, что и любое следующее правило (и, возможно, большему количеству символов). Поскольку (f)lex всегда выбирает первое правило, если возможно более одного правила, ни одно из последующих правил {UNKNOWN_TOKEN} никогда не будет совпадать.

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

Есть и некоторые другие ошибки. Например, [ ] не совпадает . Это класс символов, поэтому он соответствует точно одному символу. Единственный символ, которому он может соответствовать, заключается в том, что повторяющиеся символы в наборе не изменяют набор. ( В классе символов также нет необходимости экранировать обратную косую черту. Внутри скобок большинство символов теряют свое особое значение.) То, что ты имел в виду, было " " .

Комментарии:

1. Я попытался полностью удалить {НЕИЗВЕСТНЫЙ ТОКЕН}, но я продолжаю получать одни и те же предупреждения. И что вы имеете в виду, говоря «макросы»? Вы имеете в виду регулярные выражения?

2. @Kourkounatos: вам также придется исправить другие ошибки. Как я уже сказал, [ ] совпадает с одним , таким же, как [ ] . Таким образом, у вас есть два правила, которые совпадают , и ни одно правило, которое совпадает . Это всего лишь пример; вам придется исправить множество правил. Обратите также внимание, что макросы не раскрываются внутри скобок класса символов. [{VARIABLE}] соответствует одному символу; это в точности то же самое, что [{}ABEILRV] .

3. @Kourkounatos: строки перед %% являются определениями макросов. {name} расширяется до определения name , но только в контексте, где {} признаются особыми. Итак "{name}" , {name} и [{name}] не являются макрорасширениями.

4. Многие ваши правила неправильно используют классы символов. Пожалуйста, перечитайте документацию для шаблонов . Кроме того, начните с нескольких правил и заставьте их работать. Затем добавьте еще. Многих ваших правил вообще не должно быть; они принадлежат синтаксическому анализатору, а не лексическому анализатору.

5. На самом деле я создаю парсер. Извините за мою ошибку. Хорошо,я исправлю эти ошибки и дам вам знать, что произошло