Подсветка синтаксиса / Алгоритмы лексического анализа - PullRequest
3 голосов
/ 19 июля 2011

Какой общий алгоритм используется для подсветки синтаксиса? Я реализовал простой подход с использованием чередования в регулярном выражении:

STRING_PATTERN | COMMENT_PATTERN | KEYWORD_PATTERNS

Поскольку определение того, является ли что-то строкой или шаблоном, зависит от того, что произойдет первым:

// This is a "comment"

"This is a // string"

Но с ключевыми словами все немного сложнее. Этот подход работает в моей текущей реализации, но я не уверен, что он оптимален.

Другая проблема - это порядок, в котором вы выделяете. Если вы выделяете цифры перед идентификаторами / ключевыми словами, вы можете случайно выделить число в ключевом слове ...

EDIT:

Мой плагин сейчас здесь: http://wordpress.org/extend/plugins/crayon-syntax-highlighter/

1 Ответ

6 голосов
/ 19 июля 2011

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

Вам необходимо исследовать генераторы синтаксического анализатора, такие как Antlr, которые - при наличии правильной, однозначной грамматики - способны выдавать вам токены, которые учитывают эти детали. Например. если комментарий определен как "//" до EOL, он вернет маркер комментария, который заменит любые строковые символы или что-либо внутри.

Стандартный подход для таких синтаксических анализаторов заключается в чтении в потоке символов (или, в частности, токенов) по одному за раз, поэтому выделение зависит не от порядка определяемых вами правил, а от порядка их появления в поток.

Например, строка может состоять из двух двойных кавычек и всего, что между ними (кроме другой двойной кавычки). Комментарий - это две косые черты и все до конца строки.

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

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

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

...