我正在解析一个小的声明性语言,在一个范围内你可以声明变量(带有一个类型),然后再使用,就像在大多数其他语言中一样,使用名称(没有类型).
变量的声明如下所示:
?varname ?varname1 ?varname2 - type1 ?varname3 ?varname4 ?varname5 - type2
如果省略类型,则默认类型应该object
与第一种情况类似.所以为此,我有一个特定的解析器,它返回一个我自己的域对象列表LiftedTerm
(你可以假设它是一个带有变量名称和变量类型的元组,实际上它里面还有一些东西,但不相关对于这个问题):
def typed_list_variables : Parser[List[LiftedTerm]]= typed_variables.+ ^^ { case list => list.flatten.map(variable => LiftedTerm(variable._1, variable._2 match { case "object" => ObjectType case _ => TermType(variable._2) })) } def typed_variables = ((variable+) ~ (("-" ~> primitive_type)?)) ^^ { case variables ~ primitive_type => for (variable <- variables) yield variable -> primitive_type.getOrElse("object") } def variable = """\?[a-zA-Z][a-zA-Z0-9_-]*""".r def primitive_type = """[a-zA-Z][a-zA-Z0-9_-]*""".r
这一切都很好.
现在,在相同的"范围"中,我必须解析存在对这些变量的引用的部分.该变量显然不会再次完整声明.因此,在上面的示例中,?varname1
使用的位置将不包括type1
.但是,当我解析其余的输入时,我希望得到正确LiftedTerm
对象的引用,而不仅仅是一个字符串.
我有一些递归结构,所以我不希望在顶级解析器上进行这种映射.我不希望在我的RegexParsers
对象中对这些进行"全局映射",因为大多数这些都是作用域的,并且仅与一小部分输入相关.
有没有办法将上下文信息传递给解析器?理想情况下,我将LiftedTerm
(或者更好的是变量名称中的映射String -> LiftedTerm
)列表传递给递归解析器调用.
(抱歉,如果这是显而易见的事情,我仍然是Scala的新手,甚至是解析器组合器的新手).