Обнаружение IP-адреса в RE2C
Я пытаюсь написать регулярное выражение для определения IP-адресов и числа с плавающей запятой в re2c ( http://re2c.org/). Вот регулярное выражение, которое я использую
<SYMBOL> [-+]?[0-9]+[.][0-9]+ { RETURN(FLOAT); }
<SYMBOL> [0-9]{1,3}'.'[0-9]{1,3}'.'[0-9]{1,3}'.'[0-9]{1,3} {RETURN (IPADDR); }
Всякий раз, когда я компилирую, выдает ошибку о том, что какой-то YYMARKER не объявлен. Но если я использую только одно из правил, компиляция идет хорошо. Я предполагаю, что у re2c есть проблемы с регулярным выражением на основе обратного отслеживания, поскольку оба правила имеют большой набор данных с общим префиксом (например, 192.132 может начинать как число с плавающей запятой, так и IP-адрес).
Вот командная строка, которую я использую, чтобы сначала сгенерировать файл токенизатора. Сам re2c не выдает никакой ошибки.
re2c -c -o tokenizer.c tokenizer.re
Но когда я компилирую файл C, я получаю следующую ошибку.
tokenizer.c: In function 'getnext_querytoken':
tokenizer.c:74: error: 'YYMARKER' undeclared (first use in this function)
tokenizer.c:74: error: (Each undeclared identifier is reported only once
tokenizer.c:74: error: for each function it appears in.)
Есть ли способ, которым я могу решить эту проблему?
2 ответа
@sushil, вы правы: YYMARKER является частью re2c API.
Тем не менее, re2c не "испытывает проблемы с регулярным выражением на основе обратного отслеживания, поскольку оба правила имеют большой набор данных". Сгенерированные re2c лексеры повторяют ввод только один раз (сложность линейна). YYMARKER необходим из-за перекрывающихся правил, как описано в этом примере: http://re2c.org/examples/example_01.html:
YYMARKER (строка 5) необходим, потому что правила перекрываются: резервное копирование входной позиции самого длинного успешного совпадения. Скажем, у нас есть перекрывающиеся правила "a" и "abc" и входная строка "abd": к тому времени, когда "a" совпадает, все еще есть шанс сопоставить "abc", но когда лексер видит "d", он должен выполнить откат. (Вы можете задаться вопросом, почему YYMARKER вообще представлен: почему бы не сделать его локальной переменной, например, yych? Причина в том, что все входные указатели должны обновляться YYFILL, как объяснено в произвольном большом вводе и примере YYFILL.)
Похоже, я не прочитал man-страницу должным образом. В соответствии с man-страницей мне нужно было вручную определить переменную YYMARKER для поддержки возврата в re2c. Вот выдержка из http://re2c.org/manual.html
YYMARKER l-значение типа * YYCTYPE. Сгенерированный код сохраняет информацию для отслеживания в YYMARKER. Некоторые простые сканеры могут не использовать это.