2009-05-08 3 views
1

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

current event next action 
IDLE $  COLOR - 
COLOR any -  OnColor() 
COLOR \n IDLE - 

Это будет вызывать действие OnColor() для каждого символа, который находится между «$» и конец линии, поэтому я могу его раскрасить. Конечно же, это может быть автоматически сгенерировано из regexp, но я действительно хочу знать, как это работает до использования тяжелой магии :). Далее идет проблема: если у меня есть правило: (хотите окрасить любую строку текста, который заканчивается с долларом, таблица перехода состояния не очень понятно:

current  event next    action 
IDLE   any -    - 
IDLE   $  DOUND_DOLLAR  - 
FOUND_DOLLAR \n IDLE    OnDollar() 
FOUND_DOLLAR any IDLE    - 

Я могу научить свою государственную машину, чтобы позвонить OnDollar (), если он обнаружил знак «$» в конце строки, но что я могу сделать, чтобы раскрасить текст, который был перед знаком знака доллара? Каковы общие шаблоны для решения таких проблем? Конечно, это будет 1 строка с регулярным выражением, но мне действительно интересно узнать, как такой парсер можно реализовать с помощью конечного автомата, и это вообще возможно.

ответ

0

Чтение «Purple Dragon Book» (sic) кажется, что современные компиляторы и интерпретаторы активно используют «заглядывать вперед» в буфер и накапливают свежий текст, поэтому они могут легко проверить несколько следующих символов и несколько предыдущих символов, чтобы получить точную лексем.

Итак, в моем примере event() необходимо посмотреть следующий и предыдущий символы, чтобы определить тип лексемы, который может быть накоплен.

1

Если вы ограничены цветом одного символа за раз (т.е. у вас нет буферизации, просмотра, перекрашивания или маркировка capa bility), то это невозможно.

В противном случае, если у вас есть такие возможности, это можно сделать; техника зависит от того, что доступно.

  • Повторное окрашивание - есть действие, которое может перекрасить n символов назад. Очевидно, это тривиальное решение.

  • Буферизация/маркировка - действие, которое помещает символ в конец буфера/устанавливает именованный знак в источнике, а не пропускает символ. Затем, когда вы позже узнаете, что делать, выполните действие, которое так или иначе выполняет буфер, или сбрасывается с именованного знака. Повторное окрашивание более 1 персонажа с этим несколько усложняется.

  • Lookahead - имеет спекулятивные переходы, то есть использовать NFA вместо DFA.

+0

У меня вообще нет ограничений, хочу знать «правильный» способ решить такую ​​задачу в реальном слове. Конечно, я могу создать временные буферы и возиться с дополнительными флагами/множественными состояниями, но я чувствую, что это как-то выпадает из простой конструкции переходного гобелевого компьютера :( – grigoryvp

+0

Я не шучу, «Глаз ада» - это невозможно окрасить символ перед символом, который запускает раскраску, если у вас нет какой-либо буферизации или какого-либо вида. –

+0

Возможно, целесообразно сначала сканировать текст в лексеме и анализировать маркеры, анализируя не только текст лексим-лучей, но и позиционировать друг друга? Или, может быть, это известный трюк, который позволяет машине состояний таблицы перехода накапливать данные более умным способом? :) – grigoryvp

0

Большинство колоризаторов всегда работают на более крупном блоке, говорят целую линию (что достаточно в большинстве случаев) плюс флаг «утечка», например, для многострочных комментариев. См. Пример Qt Syntax Highlighter для такого API.

+0

В синтаксисе синтаксиса Qt используется стандартная грамматика регулярного выражения, которая является видом более высокого уровня :). Мне интересно узнать, как создавать правильные машины состояний, прежде чем создавать их автоматически с помощью regexp magic :). – grigoryvp

+0

true, но весь макет API, какие данные ему нужны и как он прерывает ввод данных, должен дать вам много идей, как подойти проблема. Используйте источник, Люк! –

Смежные вопросы