Существует несколько различных свойств парсера и базовых классов для разных целей.
Основная черта 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
.