#c #parsing
#c #Синтаксический анализ
Вопрос:
Недавно я был занят с некоторым фреймворком PHP — кстати, совершенно не по теме.
В любом случае, у меня есть определенные файлы html / шаблонов, которые я хотел бы разобрать с помощью C (не спрашивайте меня почему, это просто потому, что я хочу написать это на C ). Кроме того, это может оказаться первой полезной вещью, которую я когда-либо напишу на C .
В любом случае, чтобы вернуться к проблеме, представьте, что у меня есть файл, подобный следующему:
<table>
<tr>
<th>ID</th>
<th>Title</th>
<th>Actions</th>
</tr>
{foreach from="$pages => $page"}
<tr>
<td>{$page.Id()}</td>
<td>{$page.Title()}</td>
<td><a href="page/edit/{$page.Id()}/">Edit</a> | <a href="page/delete/{$page.Id()}/">Delete</a></td>
</tr>
{foreachelse}
<tr>
<td colspan="3">There are no pages to be displayed</td>
</tr>
{/foreach}
</table>
И результат должен быть:
<table>
<tr>
<th>ID</th>
<th>Title</th>
<th>Actions</th>
</tr>
<?php if(count($pages) > 0): ?>
<?php foreach($pages as $page): ?>
<tr>
<td><?php echo $page->getId(); ?></td>
<td><?php echo $page->getTitle(); ?></td>
<td><a href="page/edit/<?php echo $page->getId(); ?>/">Edit</a> | <a href="page/delete/<?php echo $page->getId(); ?>/">Delete</a></td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr>
<td colspan="3">There are no pages to be displayed</td>
</tr>
<?php endif; ?>
</table>
Возможно, вам не совсем понятно, почему я это делаю, но это остается проблемой, которая в любом случае применима где-то еще.
В любом случае, требуются некоторые прямые и обратные запросы и изменения в выходных файлах. Каков правильный подход к этой проблеме?
Комментарии:
1. Почему бы просто не написать сайт на обычном PHP?
2. Это было не то, к чему я стремился ;). Это потому, что я хочу писать на C . Видите ли, PHP становится скучным, C становится немного сложнее, и написать такой синтаксический анализатор сложнее, чем просто написать его на обычном PHP.
3. Я всегда восхищаюсь теми, кто любит хорошие задачи ;).
Ответ №1:
Вы можете написать парсер ручной работы, который может быть нетривиальным, в зависимости от ваших реальных требований. Следующий лучший выбор — использовать синтаксические анализаторы C , подобные BNF, например boost::spirit, поэтому вам не нужно потеть, обрабатывая правила синтаксического анализа самостоятельно. Вам все равно нужно будет написать правильные семантические действия для преобразования { … } в php.
Комментарии:
1. Я загляну в библиотеку Boost Spirit, она выглядит многообещающе. Однако мне все еще было интересно, использую ли я парсер ручной работы. Какой был бы хороший способ решить эту проблему, например, с помощью очереди или стека?
Ответ №2:
На мой взгляд, правильным подходом было бы не заново изобретать колесо (то есть писать свой собственный анализатор), а использовать существующую библиотеку, которая упростит работу и отнимет у вас меньше времени. Одной из таких библиотек C может быть wxHTMLParser или wxHTML.
Комментарии:
1. Его входной файл не является допустимым html.
Ответ №3:
Для проблем такого типа я склоняюсь к регулярному выражению. Используя либо boost::regex
, либо классы регулярных выражений GNU, либо любую другую библиотеку. Идентификация этих маркеров и их преобразование — это в основном поиск по регулярным выражениям и замена (с параметрами для имен переменных, значений и т.д.), И вам не нужно писать код для фактического анализа всего HTML и специальных вставок.