Разница между RegexpParsers, StandardTokenParsers и JavaTokenParsers в scala - PullRequest
17 голосов
/ 30 апреля 2010

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

Ответы [ 2 ]

22 голосов
/ 30 апреля 2010

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

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

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

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

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

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

6 голосов
/ 30 апреля 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...