Лекс распознает [как часть цепочки букв вместо символа
Я пишу простую программу yacc, которая проверяет синтаксис. Я должен быть в состоянии сделать что-то вроде
int a[100];
У меня есть много печатных заявлений в моей программе, чтобы вы могли видеть, что происходит. Вместо того чтобы сказать
INT found
VAR NAME found
CHAR found
NUMBER found
CHAR found
CHAR found
это говорит
INT found
VAR NAME found
VAR NAME found
syntax error
В моем файле YACC у меня есть
type VARNAME '[' NUM ']' ';'
у меня есть файл lex
[=\-+*/%&|\[\]();{}<>!] { //return the symbols
fprintf(stderr,"CHAR found\n");
return (*yytext);
}
[a-zA-z][a-zA-Z0-9]* { //ID can start with any letter and end with letters and numbers.
fprintf(stderr,"VAR NAME found\n");
yylval.string=strdup(yytext);
return(ID);
}
который является единственным кодом, относящимся к этой проблеме. Из того, что я вижу, нет никаких противоречий с CFG, поэтому я не уверен, в чем проблема.
2 ответа
Я полностью согласен с предложением EJP заменить этот длинный список специальных символов простым резервным правилом в конце определения вашего сканера. Но это не причина вашей проблемы.
Причиной является просто опечатка: ваш шаблон для первого символа ID
является [a-zA-z]
, вместо [a-zA-Z]
, Первый шаблон соответствует символам между Z и a, которые включают [ и ]. Так, [100]
является ID
согласно вашей спецификации.
Лично я предлагаю использовать классы символов Posix, написав:
[[:alpha:]][[:alnum:]]*
или, если вы хотите включить _ (который также находится между Z и a, как это происходит):
[[:alpha:]_][[:alnum:]_]*
Код, который вы разместили, не завершен. Там нет ничего, что распознает ключевое слово int,
и у вас нет правила, которое распознает числовые литералы.
Вы переоцениваете. Избавьтесь от первого правила и поместите правило всеобщего отслеживания после правила идентификатора:
. return yytext[0];
Сюда:
- Любые допустимые односимвольные специальные символы обрабатываются автоматически.
- Любые недопустимые односимвольные специальные символы обрабатываются синтаксическим анализатором как исправление ошибок.