Написание токенизатора, с чего начать?

#c #css #tokenize

#c #css #токенизировать

Вопрос:

Я пытаюсь написать токенизатор для CSS на C , но я понятия не имею, как написать токенизатор. Я знаю, что он должен быть жадным, считывать как можно больше входных данных для каждого токена, и теоретически я знаю, как я мог бы поместить это в код.

Я посмотрел на Boost.Tokenizer, и это кажется приятным, но мне это совершенно не помогает. Это, конечно, хорошая оболочка для токенизатора, но проблема заключается в написании разделителя токенов, функции TokenizerFunction в терминах Boost.

Я понятия не имею, как написать этот токенизатор, есть ли какие-нибудь «аккуратные» способы сделать это, например, что-то, что очень напоминает сам синтаксис?

Пожалуйста, обратите внимание, я не ищу синтаксический анализатор! Моему приложению не обязательно понимать CSS, просто прочитайте файл CSS в общий внутренний токенизированный формат, обработайте некоторые вещи и снова выведите.

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

1. Обратите внимание, что правила конца файла допускают токенизацию CSS с использованием готового токенизатора … интересно. Предполагая, что это вообще возможно.

Ответ №1:

Написание «правильного» лексера и / или синтаксического анализатора сложнее, чем вы могли подумать. И это может стать уродливым, когда вы начнете иметь дело со странными угловыми случаями.

Мой лучший совет — потратить некоторое время на изучение правильной системы лексеров / синтаксических анализаторов. CSS должен быть довольно простым языком для реализации, и тогда вы приобретете удивительно мощный инструмент, который сможете использовать для всех видов будущих проектов.

Я старый пердун® и использую lex / yacc (или вещи, использующие тот же синтаксис) для проектов такого типа. Впервые я научился использовать их еще в начале 80-х, и это вернуло усилия по их изучению много-много раз.

Кстати, если у вас есть что-то, приближающееся к BNF языка, с lex / yacc может быть до смешного легко работать.

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

1. Lex и Yacc по-прежнему являются самым простым способом сделать это.

2. Я не знаком с Lex amp; Yacc, это библиотека, язык или?

3. @nightcracker Google, Google, Google!

4. @Henry: Да, но я действительно в замешательстве. Фрагмент кода находится на странице википедии, но, похоже, это C, смешанный с чем-то, что предположительно является lex.

5. @nightcracker — со страницы википедии, которую вы упомянули: «Lex считывает входной поток, определяющий лексический анализатор, и выводит исходный код, реализующий лексер на языке программирования C.» Кажется довольно ясным…

Ответ №2:

Boost.Spirit.Qi был бы моим первым выбором.

Spirit.Qi разработан как практичный инструмент синтаксического анализа. Возможность сгенерировать полностью рабочий анализатор на основе формальной спецификации EBNF, встроенной в C , значительно сокращает время разработки. Программисты обычно подходят к синтаксическому анализу, используя специальные хаки с примитивными инструментами, такими как scanf. Даже библиотеки регулярных выражений (такие как boost regex) или сканеры (такие как Boost tokenizer) плохо масштабируются, когда нам нужно написать более сложные анализаторы. Попытка написать даже умеренно сложный синтаксический анализатор с использованием этих инструментов приводит к созданию кода, который трудно понять и поддерживать.

Учебные пособия Qi даже заканчиваются внедрением синтаксического анализатора для языка XMLish; написание грамматики для CSS должно быть значительно проще.

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

1. Один мир предостережения: ставит компиляторов на колени! Вы хотите, чтобы собственно синтаксический анализатор находился в одной единице перевода и сам по себе, чтобы перекомпилировать его как можно меньше раз. Еще лучше: возможность разрезать на несколько частей, каждая в своем TU.