Определения Flex являются макросами, и flex реализует их таким образом: когда он видит {defn}
в шаблоне, он заменяет его на то, что определено defn
(в скобках, как правило, во избежание проблем с приоритетами операторов). Он не расширяет макросы в определении макроса, поэтому подстановка макроса может содержать больше ссылок на определения, которые, в свою очередь, должны быть заменены.
Поскольку подстановка макроса является безусловной, использование рекурсивных макросов невозможно, включая макросы, которые являются косвенно рекурсивными. Который твой. Flex не проверяет это условие, в отличие от препроцессора C; он просто продолжает подстановку в бесконечном l oop до тех пор, пока не закончится пространство.
(Flex реализован с использованием самого себя; он выполняет подстановку макросов, используя unput
. unput
не изменит размер входного буфера, так что «не хватает места» означает, что во внутреннем буфере flex во Flex вошли полные подстановки.)
Используемая вами стратегия будет прекрасно работать в качестве контекстно-свободной грамматики. Но это не изгиб. Flex - это регулярные выражения. Шаблон, который вы хотите сопоставить, может быть описан с помощью регулярного выражения - «грамматика», которую вы написали с помощью макросов flex, - это обычная грамматика, но она не является регулярным выражением, и flex не сделает ее из вас, к несчастью. Это твоя работа.
Не думаю, что это будет очень красивое регулярное выражение. На самом деле, я думаю, что это может быть огромным. Но я не пытался разобраться с этим ..
Существуют гибкие приемы, которые можно использовать, чтобы избежать создания регулярного выражения. Например, вы могли бы построить свой конечный автомат из условий запуска flex и затем сканировать по одному символу за раз, когда каждый просканированный символ выполняет переход состояния или выдает ошибку. (Используйте more()
, если вы хотите вернуть всю строку, отсканированную в конце.)