Теория синтаксического анализа и выделения синтаксиса в реальном времени - PullRequest
15 голосов
/ 22 мая 2011

Я пытаюсь понять, как мне следует реализовать подсветку синтаксиса в реальном времени при обработке очень большой строки. Я в замешательстве. Вот что я знаю:

(Предположим, у меня есть функция parsedString parseString(rawString))

  1. Вызовите parseString(entireText) и замените текущую строку возвращенной проанализированной (и стилизованной и т. Д.) Строкой при каждом изменении текста. Это кажется плохим подходом при работе с большими данными.

  2. Кто-то предложил проанализировать отредактированный диапазон и заменить текущую необработанную отредактированную строку разобранной строкой parseString(editedRange).

Метод (1) достаточно понятен. Что я не могу понять, так это (2). При вводе для каждого символа, добавляемого в строку, уведомление запускается, и один символ анализируется (и возвращается как есть).

Например, если мне нужны красные селекторы при разборе файла .css, как я могу понять, когда есть завершенный селектор, за которым следует {, который должен быть окрашен? Я предполагаю, что есть какой-то способ отложить анализ до совпадения. Как вы реализуете это?

Я не ищу работающее приложение. Хорошее объяснение было бы также полезно.

Заранее спасибо.

1 Ответ

14 голосов
/ 22 мая 2011

Для повторного разбора инкрементных изменений вам потребуется API более низкого уровня для вашего анализатора.

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

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

Итак, вам нужен API, например:

parsedString parseIncrementally(parserState, rawString);
...