гибкий сканер pu sh -полное переполнение с автоматами - PullRequest
1 голос
/ 03 мая 2020

Эй, ребята, мне трудно с этой проблемой. «Напишите гибкий код, который распознает цепочку с алфавитом {0,1}, по крайней мере, с 5 символами, и с каждыми последовательными 5 символами будет по крайней мере 3 1» Я думал, что решил, но я новичок, используя Flex, поэтому я получаю это "переполнение сканера pu sh -back переполнение". вот мой код '' '

%{
#define ACCEPT  1
#define     DONT    2
%}
delim       [ \t\n\r]
ws          {delim}+
comb01  00111|{comb06}1
comb02  01011|{comb07}1
comb03  01101|{comb08}1
comb04  01110|({comb01}|{comb09})0
comb05  01111|({comb01}|{comb09})1
comb06  10011|{comb10}1
comb07  10101|{comb11}1
comb08  10110|({comb02}|{comb12})0
comb09  10111|({comb02}|{comb12})1
comb10  11001|{comb13}1
comb11  11010|({comb03}|{comb14})0
comb12  11011|({comb03}|{comb14})1
comb13  11100|({comb04}|{comb15})0
comb14  11101|({comb04}|{comb15})1
comb15  11110|({comb05}|{comb16})0
comb16  11111|({comb05}|{comb16})1
accept  {comb01}|{comb02}|{comb03}|{comb04}|{comb05}|{comb06}|{comb07}|{comb08}|{comb09}|{comb10}|{comb11}|{comb12}|{comb13}|{comb14}|{comb15}|{comb16}
string  [^ \t\n\r]+
%%
{ws}        { ;}
{accept}    {return ACCEPT;}
{string}    {return DONT;}
%%
void main () {
    int i;
    while (i = yylex ())
        switch (i) {
            case ACCEPT:
                printf ("%-20s: ACCEPT\n", yytext); 
                break;
            case DONT:
                printf ("%-20s: Reject\n", yytext); 
                break;
        }
}

' ''

1 Ответ

3 голосов
/ 03 мая 2020

Определения Flex являются макросами, и flex реализует их таким образом: когда он видит {defn} в шаблоне, он заменяет его на то, что определено defn (в скобках, как правило, во избежание проблем с приоритетами операторов). Он не расширяет макросы в определении макроса, поэтому подстановка макроса может содержать больше ссылок на определения, которые, в свою очередь, должны быть заменены.

Поскольку подстановка макроса является безусловной, использование рекурсивных макросов невозможно, включая макросы, которые являются косвенно рекурсивными. Который твой. Flex не проверяет это условие, в отличие от препроцессора C; он просто продолжает подстановку в бесконечном l oop до тех пор, пока не закончится пространство.

(Flex реализован с использованием самого себя; он выполняет подстановку макросов, используя unput. unput не изменит размер входного буфера, так что «не хватает места» означает, что во внутреннем буфере flex во Flex вошли полные подстановки.)

Используемая вами стратегия будет прекрасно работать в качестве контекстно-свободной грамматики. Но это не изгиб. Flex - это регулярные выражения. Шаблон, который вы хотите сопоставить, может быть описан с помощью регулярного выражения - «грамматика», которую вы написали с помощью макросов flex, - это обычная грамматика, но она не является регулярным выражением, и flex не сделает ее из вас, к несчастью. Это твоя работа.

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

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

...