Парсер против лексера и XML

Сейчас я читаю об архитектуре компиляторов и синтаксических анализаторов и меня интересует одна вещь... Когда у вас есть XML, XHTML, HTML или любой язык на основе SGML, какова будет роль лексера здесь и какие будут токены?

Я читал, что токены похожи на слова, подготовленные лексером для анализа. Хотя у меня нет проблем с поиском токенов для языков C, C++, Pascal и т. Д., Где есть ключевые слова, имена, литералы и другие словоподобные строки, разделенные пробелами, с XML у меня есть проблема, потому что нет ' т любые слова! Это только обычный текст, чередующийся с разметкой (тегами).

Я подумал, что эти теги и фрагменты простого текста могут быть токенами, что-то вроде этого: [TXT][TAG][TAG][TXT][TAG][TXT][TAG][TAG][TXT]..., Это было бы вполне разумно, так как SGML не волнует, что находится внутри разделителей разметки. < а также > (ну, он распознает специальные инструкции обработки и определения, когда он найдет ? или же ! как следующий персонаж; комментарии также относятся к этой группе), и токенайзер SGML может стать основой для синтаксического анализатора XML/HTML/XHTML.

Но потом я понял, что может быть < символы, вставленные в разметку как часть другого синтаксиса: значения атрибутов:-/ Даже если не очень хорошая идея поместить < символы внутри значений атрибутов (лучше использовать &lt; для этого), многие браузеры и редакторы имеют дело с этим и относятся к этим < как часть значения атрибута, а не разделителя тегов.

Это немного усложняет ситуацию, потому что я не вижу способа распознать такую ​​разметку простым детерминированным конечным автоматом (DFA) в лексере. Похоже, он требует отдельного контекста для автомата, когда он находится внутри тега, и другого контекста, когда он встречает значение атрибута. Я думаю, что для этого потребуется стек состояний / контекстов, поэтому DFA может с этим не справиться. Я прав?

Что ты думаешь? Хорошо ли делать токены из тегов (разметки) и простого текста?

Здесь: http://www.antlr.org/wiki/display/ANTLR3/Parsing+XML
используется какая-то другая техника: они относятся < а также > (а также </ а также />) как отдельные токены, так и внутри тегов, которые они используют GENERIC_ID как символ и т. д. Они обычно переносят большую часть работы на анализатор. Но они также должны изменить контексты для токенизатора: они используют различный контекст в простом тексте и различаются в разметке (но я думаю, что они забыли о контексте значений атрибутов, потому что первое появление > закончу тег в своем лексере).

Итак, каков наилучший подход для разбора SGML-подобных языков? Лексер действительно используется там? Если да, какие строки составляют токены?

1 ответ

Решение

Создав парсеры XML и HTML, у меня есть мнения.

Лексемы вообще должны быть узнаваемыми элементами языка.

Для XML и HTML они в основном соответствуют

  • ТАГБЕГИН, вещи в форме <ИМЯ
  • TAGEND, в форме >
  • TAGCLOSE, в форме
  • TAGENDAND ЗАКРЫТЬ формы /> (только XML)
  • ATTRIBUTENAME, в форме NAME
  • EQUALSIGN, будучи точно =
  • ATTRIBUTEVALUE, являющийся значением точной символьной строки, представленной атрибутом, независимо от кавычек (или даже отсутствия кавычек, для устаревшего HTML). Если в атрибуте есть экранированные коды символов, этот код следует преобразовать в их действительный код символа.
  • СОДЕРЖАНИЕ, которое является текстом между TAGEND и TAGBEGIN. Как и ATTRIBUTEVALUES, любые экранированные символы должны быть преобразованы, поэтому CONTENT между foo & lt; bar преобразуется в текст foo Если вы хотите сохранить вызовы сущностей в качестве отдельных токенов, вы можете сделать это, выполнив потоки токенов CONTENT и ENTITYINVOCATION между TAGEND и TAGSTART; зависит от того, какова ваша цель.

Мы можем спорить о том, хотите ли вы создать токен для комментариев HTML/XML или нет. Если вы делаете, вы делаете.

Если мы игнорируем сложности DTD и схем для XML, это все, что вам действительно нужно.

Как это делает лексер, сложнее; с XML и HTML, есть много беспорядка, касающегося выходов во входном потоке, <[CDATA...]> (если я имею это право), который является просто забавной цитатой и исчезает, когда лексема CONTENT производится. Чтобы справиться со всем этим, вам нужен довольно сложный лексерский движок. И да, на практике вам нужны разные лексические состояния ("режимы") для обработки разных частей текста. У меня в основном есть один основной режим для обработки вещей внутри <... > и один основной режим для обработки CONTENT.

Другие вопросы по тегам