Как прочитать идентификатор «класс» во Flex?

Я пытаюсь написать компилятор для языка COOL и сейчас занимаюсь лексическим анализом. Конкретно, Flex соответствует наибольшему шаблону, насколько я понимаю.

Таким образом, если у вас есть во Flex:

class A inherits B

Теперь, если мой токен для class возвращается по следующей схеме:

^"class"   return CLASS;

Для меня inherits маркер:

^"class"[ ]+[a-zA-Z]+[0-9]?[ ]+"inherits"[ ]+ return INHERITS;

Теперь, когда flex соответствует наибольшему шаблону, он всегда будет возвращаться INHERITS и никогда не класс. Есть ли решение этой проблемы?

Я могу здесь вернуть токен для class в одиночестве. Но как мне вернуть токен для inherits поскольку ему ДОЛЖЕН предшествовать class токен и его имя, за которым следует еще один строковый токен?

Но если я попытаюсь наложить ограничения на inherits, тогда flex будет соответствовать наибольшему шаблону, а не одному классу.

Тогда я должен возвращать перечисления / число для идентификатора класса индивидуально? И если я сделаю это, как я могу идентифицировать «наследует» идентификатор?

РЕДАКТИРОВАТЬ:

class A inherits B {
main(): SELF_TYPE{...}
}

Как соотносится гибкость с main? Мой рефлексер различает TypeID, который A а также main, который он заявляет ObjectID, Единственное, что он может сделать, — это смотреть вперед на парантез и, если он найдет (, он объявляет ObjectID. Но если я сделаю это, я столкнусь с той же проблемой, что и выше: flex никогда не сравнится с ( но всегда main(,

0

Решение

Вы пытаетесь сделать слишком много во Flex, и, возможно, вы неправильно понимаете роль и границы лексической фазы. Вы не должны пытаться анализировать предложение целиком с помощью одного регулярного выражения Flex. Работа Flex заключается в том, чтобы потреблять поток текста и преобразовывать его в поток целочисленных токенов. Предложение, которое вы предоставили:

 class A inherits B

представляет несколько токенов из языка, который требует синтаксического анализа. Flex — это не парсер, это лексический сканер / токенизатор. (Технически это синтаксический анализатор байтов или символов, но вы хотите «анализировать» атомарные единицы, которые представляют слова вашего языка, а не символы).

Таким образом, есть 4 различных токена (атомные единицы), также известные как ТЕРМИНАЛЫ в вышеприведенном предложении: [КЛАСС, А, НАСЛЕДОВАНО, В].
Вам нужно правило IDENTIFIER для Flex, чтобы все, что не соответствует токену, перешло к IDENTIFIER, поэтому токены, возвращаемые Flex анализатору:

 CLASS IDENTIFIER INHERITS IDENTIFIER

Работа для Flex состоит в том, чтобы анализировать каждое слово / токен и преобразовывать текст в различные целочисленные значения для использования Bison или любым другим анализатором.

У вас обычно есть грамматика Yacc / Bison BNF для обработки:

 class_decl:
CLASS IDENTIFIER
| CLASS IDENTIFIER INHERITS IDENTIFIER
;

Таким образом, ваше правило Lex будет таким, и вам нужно вернуть токен IDENTIFIER в анализатор, при этом прикрепив реальный символ (A, B). Вы получаете это из переменной yytext:

LETTER            [a-zA-Z_]
DIGIT             [0-9]
LETTERDIGIT       [a-zA-Z0-9_]
%%

"class"         return(CLASS);
"inherits"      return(INHERITS);

{LETTER}{LETTERDIGIT}* {
yylval.sym = new Symbol(yytext);
yylval.sym->line = line;
fprintf(stderr, "TOKEN IDENTIFIER(%s)\n", yytext);
return(IDENTIFIER);
}

Если вы действительно пытаетесь сделать все это во Flex, то это возможно, но вы получите беспорядок, например, если вы попытаетесь проанализировать HTML с помощью регулярных выражений … 🙂

2

Другие решения


По вопросам рекламы [email protected]