Синтаксический анализ / преобразование линейной разметки в полезную структуру данных

#parsing #data-structures #lexical-analysis

#синтаксический анализ #структуры данных #лексический анализ

Вопрос:

Проблема*

Даны некоторые данные (текст), к которым применен стиль с помощью слабо определенной разметки, например:

 The [blower]cat[elower] [weight 15]sat[normal] on the mat.[newline]
 

В идеале это было бы представлено как что-то вроде:

 The <text class="lower">cat</text> <strong>sat</strong> on the mat.<br />
 

Разметка обладает следующими свойствами:

  • Тег представляет собой инструкцию для форматирования текста заданным способом с этого момента и далее
  • Конечный тег может существовать, но только для небольшого набора тегов. Другие теги являются линейными (см. Пункт 1)
  • Каждый тег имеет свое собственное поведение и может по-разному влиять на ранее примененные теги
  • Некоторая вложенность подразумевается из линейных тегов, добавляющих или перезаписывающих существующие стили
  • Метаданные могут находиться за пределами тегов (например. [beg] [xyz]cmd [end1] — все это связано с тегами, без содержимого)

Требования

  • Определите правила взаимодействия тегов (например. Тег стиля, такой как [bold], закрывается другим тегом стиля, таким как [normal] или [light])
  • Вложение некоторого содержимого (теги, которые не перезаписываются, как указано выше, будут вложены и соответственно разорваны)
  • Определение отображений из четко определенного представления в памяти в некоторый выходной формат

Мысли

  • Разбор в DOM-подобную структуру — попытка сгруппировать теги в «наборы». При обнаружении тега закройте активный тег для этого набора и откройте новый. Это создает <tag>содержимое</tag> . Проблемы, связанные с правильным вложением и закрытием / повторным открытием тегов, чтобы вы не сталкивались с ситуациями перекрытия, такими как <b>text<i>text</b>text</i>, раздражают, но достаточно прямолинейны.

Как бы вы приступили к разработке структуры данных или метода анализа содержимого таким образом, чтобы набор правил мог помочь преобразованию в четко определенную структуру?

В качестве альтернативы, любые предложения по полям / областям, на которые вы бы обратили внимание при решении такого рода проблем?

* Проблема реального мира

Комментарии:

1. Мое домашнее задание вызывает трепет…

2. Действительно? Тогда это требует некоторой корректировки, я нахожусь в реальном мире уже почти 4 года. 🙂

Ответ №1:

Эта проблема изоморфна (по крайней мере, так, как вы ее описали до сих пор) XML. У вас есть синтаксис, который вводит и завершает разметку, и он поставляется в основном парами [blower] …[elower] и [weight 15] …[обычный] со случайной автономной [новой строкой].

Итак, если вы знаете, как создать анализатор XML с тегами, вы знаете, как это сделать.

Если вы этого не сделаете, вам просто нужна грамматика (в EBNF) и генератор синтаксического анализа:

 document =  fragment* ;

fragment = TEXT ;
fragment = '[blower]' fragment '[elower]' ;
fragment = '[weight' NATURAL ']' fragment '[normal]' ;
fragment =  other_start_tag fragment other_end_tag ;
fragment = '[newline]' ;
 

Для этого требуется довольно простой лексер и довольно простой анализатор. (См. FLEX и YACC в качестве примеров).
Вы можете создать свой DOM как набор узлов дерева во время выполнения синтаксического анализатора, присоединив действия к правилам грамматики (см. Документацию YACC). Многие другие генераторы синтаксических анализаторов также позволят вам создавать дерево по мере анализа.

Комментарии:

1. Хорошо объяснено, спасибо. Меня интересуют только отдельные теги, которые с этого момента вносят некоторые изменения в любой текст или до тех пор, пока другой тег не получит приоритет. Есть ли какой-либо способ представить это?

2. Не путайте «синтаксический анализ» с «семантикой». Если у вас есть тег, который может отображаться где угодно, в грамматике это просто тег, даже если есть какой-то другой отменяющий тег, разрешенный в любом месте после. Итак, либо теги объединяются в пару (делайте, как указано выше), либо они не вкладываются красиво (делайте их как отдельные теги). Они означают то, как вы интерпретируете построенное дерево, когда вы поднимаетесь по нему.

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