Сопоставление токенов, несущих значения, с комбинаторами парсера Scala

У меня есть тип токенов, которые я хочу проанализировать с помощью Scala util.parsing.combinator.Parsers. Мой класс токенов выглядит примерно так:

abstract class Token ()

case class T_Semicolon () extends Token {} // represents ;                                                                                                                            
case class T_LeftBracket () extends Token {} // represents (                                                                                                                          
....                                                                                                          
case class T_Identifier ( s : String ) extends Token {}
case class T_Integer ( n : Int ) extends Token {}

Я хотел бы построить парсер Scala с обычными комбинаторами ~ ~> <~ | ... следующим образом.

object StandAloneParser extends Parsers {

   import Token._
   override type Elem = Token

   val prog = rep1 ( dec )
   val dec = T_Def () ~> T_Identifier ( id ) ~ ...

Однако сопоставление с образцом не позволяет мне сопоставить T_Identifier ( id ), потому что переменная id не объявлена. Кого я могу решить с этой проблемой?


person Martin Berger    schedule 13.08.2014    source источник


Ответы (1)


Ваш пример не очень ясен, но я думаю, вы хотите что-то вроде этого:

lazy val identifier: Parser[String] =
  acceptMatch("identifier", { case T_Identifier(id) => id })

Также обратите внимание, что я использую lazy val, а не просто val. Поскольку синтаксические анализаторы, как правило, имеют много взаимозависимостей и могут быть даже рекурсивными, обычно это хорошая идея.

Затем вы использовали бы этот парсер identifier в парсере dec:

lazy val dec = T_Def () ~> identifier ~ ...
person DaoWen    schedule 13.08.2014
comment
@MartinBerger - ваш пример не будет компилироваться, как показано, потому что вы ссылаетесь на dec в prog до объявления dec. Использование def вместо val решает эту проблему, но использование lazy val лучше, если вы хотите кэшировать результаты парсера. - person DaoWen; 14.08.2014