Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Scala中修改具有类型化特征的类_Scala_Typetraits_Parser Combinators - Fatal编程技术网

在Scala中修改具有类型化特征的类

在Scala中修改具有类型化特征的类,scala,typetraits,parser-combinators,Scala,Typetraits,Parser Combinators,我最近一直在玩Scala,在使用解析器组合器时,我在扩展它们时遇到了一些问题。基本上,我想做的就是这样 import scala.util.parsing.combinator.RegexParsers abstract class Statement case object Foo extends Statement case object Bar extends Statement case object Baz extends Statement class Program(stat

我最近一直在玩Scala,在使用解析器组合器时,我在扩展它们时遇到了一些问题。基本上,我想做的就是这样

import scala.util.parsing.combinator.RegexParsers

abstract class Statement

case object Foo extends Statement
case object Bar extends Statement
case object Baz extends Statement

class Program(statements: List[Statement])

class FooBarLanguageParser extends RegexParsers {
  def program: Parser[Program] = rep(statement) ^^ (v => new Program(List() ++ v))
  def statement: Parser[Statement] = foo|bar
  def foo: Parser[Statement] = "foo" ^^ (_ => Foo)
  def bar: Parser[Statement] = "bar" ^^ (_ => Bar)
}

trait BazStatement { this: FooBarLanguageParser =>
  override def statement: Parser[Statement] = baz|this.statement  // inifinite recursion
  def baz: Parser[Statement] = "baz" ^^ (_ => Baz)
}

object Main {
  def main(args: Array[String]) {
    val normalFooBar = new FooBarLanguageParser()
    val fooBarProgram = normalFooBar.parseAll(normalFooBar.program, "foo bar")
    val extendedFooBar = new FooBarLanguageParser() with BazStatement
    val extendedFooBarProgram = extendedFooBar.parseAll(extendedFooBar.program,
       "foo bar baz")
    println(fooBarProgram.successful)
    println(extendedFooBarProgram.successful)
  }
}
在这里,我想在
BazStatement
中调用
FooBarLanguageParser
statement
方法,但是使用上面的代码,我递归地调用
BazStatement
的方法,因此它无法正常工作

我已经看了周围的答案,我知道我可以扩展这个类并使用抽象重写,或者类似这样的想法,但我认为这在这里没有任何意义,因为
BazStatement
确实是我想与我的基本解析器混合的附加功能。我绝对不想有一些随意的事情,比如

object StrangeInheritance extends BazStatement
在代码中授权


在Scala中有没有什么惯用的方法可以正确地实现这一点,或者我需要重新考虑一下应用程序的总体设计?

使用super调用supertype的方法,也可以使用traits定义顶级抽象。这个运行正常:

import scala.util.parsing.combinator.RegexParsers

abstract class Statement

case object Foo extends Statement
case object Bar extends Statement
case object Baz extends Statement

class Program(statements: List[Statement])

trait FooBarLanguageParser extends RegexParsers {
  def program: Parser[Program] = rep(statement) ^^ (v => new Program(List() ++ v))
  def statement: Parser[Statement] = foo|bar
  def foo: Parser[Statement] = "foo" ^^ (_ => Foo)
  def bar: Parser[Statement] = "bar" ^^ (_ => Bar)
}

trait BazStatement extends FooBarLanguageParser {
  override def statement: Parser[Statement] = baz| super.statement  // inifinite recursion
  def baz: Parser[Statement] = "baz" ^^ (_ => Baz)
}

object Main {
  def main(args: Array[String]) {
    val normalFooBar = new FooBarLanguageParser() {}
    val fooBarProgram = normalFooBar.parseAll(normalFooBar.program, "foo bar")
    val extendedFooBar = new FooBarLanguageParser() with BazStatement
    val extendedFooBarProgram = extendedFooBar.parseAll(extendedFooBar.program,
       "foo bar baz")
    println(fooBarProgram.successful)
    println(extendedFooBarProgram.successful)
  }
}

对不起,我迟了答复。关于这段代码的一点是,
object FooBar extensed BazStatement
将完美地工作,我将能够使用
FooBarLanguageParser
中的所有方法,我发现这有点像我希望
BazStatement
成为我的
FooBarLanguageParser
的一个单独的额外功能。实际上混合了(traits)是非常惯用的scala方式,它提供了特别的模块化。如果您想提供一种将一组谨慎行为组合到一个运行时对象中的方法,我认为这是默认选项。您可能是对的,实际上mixin在这里可能不起作用,因为很难以可扩展的方式设计顶级解析器。也许在一些实用特性中有一组通用规则,然后在这个“通用规则”特性的帮助下构建“具体的”底层解析器,会是比尝试使用继承更好的选择。谢谢你的回答。我想我会像你说的那样,用顶级特性定义一般规则和一些具体实现。