LINUX.ORG.RU

Возможно ли задать универсальный лексический анализатор

 , , лексический анализ


0

1

Всем добрый день!

Допустим есть такой код

this->buf += newPart;
std::vector<std::string> messages = tokenizer.Tokenize(this->buf);

буфер передается в токенайзер по ссылке и после этого содержит нераспаршенный хвост на конце буфера, чтобы на след. итерации получить остаток неполного сообщения и завершить парсинг.

Допустим формат мессаги такой

'+'<любые байты кроме контрольных>'-'<два байта контрольной суммы>
сейчас внутри токенайзера используется самописный лексический анализатор, который имеет три выходных состояния - сообщение, мусор, обрубок на конце сообщения.

Все вроде хорошо. Но появилась потребность использовать такую же логику для другого формата сообщений, но формат уже совершенно другой

'!'<любое кол-во латинских символов и цифр>\r\n
Форматы выгледят настолько разными, что нужно или писать отдельный лексический анализатор, либо расширять старый 3 новыми лексемами (сообщение_формат2, мусор2, обрубок2)

А что делать если появится третий формат? Писать 3 анализатор, или добавлять в текущий еще 3 лексемы?

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

Существует ли некий способ быстро и лаконично описать новый лексичский анализатор? Например через regex. Я их конечно использую время от времени, но не то что бы сильно силен в них...

★★★★★

Если объяснить в двух словах чего я хочу, то есть полследовательность

<сообщение><мусор><сообщение><сообщение><мусор><сообщение><хвост>

или

<сообщение><мусор><сообщение><сообщение><мусор><сообщение>

или

<мусор><сообщение><мусор><сообщение><сообщение><мусор><сообщение><хвост>

Я хочу выделить список сообщений и хвост если он есть. Но хочу сделать некое универсальное и расширяемое решение для разных форматов сообщений. То есть если появляется новый формат, то я хочу его добавить малой кровью.

Dudraug ★★★★★
() автор топика

Тему не читал. Ответ в заголовке - регэкс. Проходишь весь инпут регжксом, создавая в процессе объекты типа Token и запихивая их в TokenStream. Регэкс фэйлится но новом токеге? Выдаешь ошибку.

invy ★★★★★
()
Ответ на: комментарий от invy

А как выделить обрубок? Если бы надо было вытащить только токены, то все было бы просто - регеэксп итератор и все дела. Мне надо выделить множество токенов и неполный токен (в любом виде неполный) на конце инпута. Сейчас это все работает через самописный и довольно простой конечный автомат, но это как-то нерасширяемо сейчас.

Dudraug ★★★★★
() автор топика
Ответ на: комментарий от Dudraug

Автомат генерируй (как и положено) из регэкса и будет расширяемо.

invy ★★★★★
()
Ответ на: комментарий от invy

Спасибо, завтра буду изучать.

Dudraug ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.