Различие betwean RegexpParsers, StandardTokenParsers и JavaTokenParsers в scala

Я изучаю Синтаксический анализатор Combinators в scala и вижу различные способы проанализировать. Я главным образом вижу три других вида синтаксических анализаторов т.е. RegexpParsers, StandardTokenParsers и JavaTokenParsers. Я плохо знаком с парсингом и не получением идеи, как мы выберем подходящий Синтаксический анализатор согласно нашему требованию. Может любой объяснять, как эти различные синтаксические анализаторы работают и когда использовать их.

18
задан Byju Veedu 30 April 2010 в 10:32
поделиться

2 ответа

RegexpParsers позволяет вам использовать значения RE (обычно в форме "re pattern".r, но также и любой другой экземпляр Regex). Не существует предопределенных лексических производств (токенов).

JavaTokenParsers определяет лексические постановки для Java-токенов: decimalNumber, floatingPointNumber, stringLiteral, wholeNumber, ident (identifier).

StandardTokenParsers определяет лексические постановки "... для простого, Scala-подобного языка. Он анализирует ключевые слова и идентификаторы, числовые литералы (целые числа), строки и разделители". Его составляющие фактически определены в StdLexical.

7
ответ дан 30 November 2019 в 08:10
поделиться

Существует несколько различных характеристик синтаксического анализатора и базовых классов для разных целей.

Основная особенность - scala.util.parsing.combinator.Parsers . В нем есть большинство основных комбинаторов, таких как opt , rep , elem , accept и т. Д. Обязательно просмотрите документацию для этого , поскольку это большая часть того, что вам нужно знать. Фактический класс Parser определяется здесь как внутренний класс, и об этом тоже важно знать.

Еще одна важная особенность - scala.util.parsing.combinator.lexical.Scanners . Это базовая черта для парсеров, которые читают поток символов и создают поток токенов (также известных как лексеры). Чтобы реализовать эту черту, вам необходимо реализовать парсер пробелов , который считывает символы пробелов, комментарии и т. Д. Вам также необходимо реализовать метод token , который читает следующий токен. . Токены могут быть любыми, но они должны быть подклассом Scanners.Token . Лексический расширяет Сканеры и StdLexical расширяет Лексический . Первый обеспечивает некоторые полезные базовые операции (такие как цифра , буква ), тогда как последний фактически определяет и лексирует общие токены (например, числовые литералы, идентификаторы, строки, зарезервированные слова). Вам просто нужно определить разделители и зарезервированы , и вы получите что-то полезное для большинства языков.Определения токенов находятся в scala.util.parsing.combinator.token.StdTokens .

Если у вас есть лексер, вы можете определить синтаксический анализатор, который считывает поток токенов (созданный лексером) и генерирует абстрактное синтаксическое дерево. Разделение лексического анализатора и парсера - хорошая идея, поскольку вам не нужно беспокоиться о пробелах, комментариях или других сложностях в синтаксисе. Если вы используете StdLexical , вы можете рассмотреть возможность использования scala.util.parsing.combinator.syntax.StdTokenPasers , который имеет встроенные синтаксические анализаторы для преобразования токенов в значения (например, StringLit в Строку ). Я не уверен, в чем разница с StandardTokenParsers . Если вы определяете свои собственные классы токенов, вы должны просто использовать Парсеры для простоты.

Вы конкретно спрашивали о RegexParsers и JavaTokenParsers . RegexParsers - это свойство, которое расширяет Parsers одним дополнительным комбинатором: regex , который делает именно то, что вы ожидаете. Добавьте в лексер RegexParsers , если вы хотите использовать регулярные выражения для сопоставления токенов. JavaTokenParsers предоставляет некоторые синтаксические анализаторы, которые лексируют токены из синтаксиса Java (например, идентификаторы, целые числа), но без набора токенов Lexical или StdLexical .

Подводя итог, вы, вероятно, захотите два парсера: один, который читает символы и производит токены, и другой, который принимает токены и производит AST.Сначала используйте что-нибудь, основанное на Lexical или StdLexical . Используйте что-нибудь, основанное на Parsers или StdTokenParsers для второго, в зависимости от того, используете ли вы StdLexical .

22
ответ дан 30 November 2019 в 08:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: