2011-03-22 37 views
0

编辑:我能够通过在MessageParser类中更改vallazy val来解决它。我忘了我以前使用def而不是val.对其进行了测试,有人可以明确说明为什么此更改会修复它吗?斯卡拉解析器失败<init>

所以,我目前正在编写一个IRC服务器。我决定使用Scala的Combinator Parser库来帮助我解析消息。我已经能够通过测试程序正确解析消息,但是当我试图将我的解析器合并到回显服务器时,我已经写过,当我连接到服务器时收到以下错误消息:

Connected to the target VM, address: '127.0.0.1:55567', transport: 'socket' 
Exception in thread "main" java.lang.ExceptionInInitializerError 
    at IRCServer.main(IRCServer.scala) 
Caused by: java.lang.NullPointerException 
    at messages.MessageParser.<init>(MessageParser.scala:11) 
    at net.Connection.<init>(Connection.scala:14) 
    at net.Server.start(Server.scala:14) 
    at IRCServer$.<init>(IRCServer.scala:12) 
    at IRCServer$.<clinit>(IRCServer.scala) 
    ... 1 more 
Disconnected from the target VM, address: '127.0.0.1:55567', transport: 'socket' 

连接类处理来自一个ServerSocket

class Connection(socket: Socket) extends Thread { 
    private val out = new PrintStream(socket.getOutputStream) 
    private val in = new BufferedReader(new InputStreamReader(socket.getInputStream)) 
    private val parser = new MessageParser 
    override def run(): Unit = { 
     var line = "" 
     while({(line = in.readLine); line != null}) { 
      Console.println("received: " + line) 
      parser.parseLine(line.trim) 
      out.println("out: " + line) 
     } 
    } 

} 

创建一个监听器插座,下面是我的MessageParser:

class MessageParser extends JavaTokenParsers { 
    def parseLine(line :CharSequence) = { 
     parseAll(message, line) 
    } 

    val message: Parser[Any] = opt(":"~prefix)~command~opt(params) ^^ (x=> {println("message: "+x)}) 
    val prefix: Parser[Any] = nick~"!"~user~"@"~host | servername ^^ (x=> {println("prefix: " +x)}) 
    val nick: Parser[Any] = letter~rep(letter | wholeNumber | special) ^^ (x=> {println("nick: " +x)}) 
    val special: Parser[Any] = "-" | "[" | "]" | "\\" | "`" | "^" | "{" | "}" ^^ (x=> {println("special: " +x)}) 
    val user: Parser[Any] = """[^\[email protected]]+""".r ^^ (x=> {println("user: " +x)}) 
    val host: Parser[Any] = """[\w\.]+\w+""".r ^^ (x=> {println("host: " +x)}) 
    val servername: Parser[Any] = host ^^ (x=> {println("servername: " +x)}) 
    val command: Parser[Any] = """([A-Za-z]+)|([0-9]{3})""".r ^^ (x=> {println("command: " +x)}) 
    val params: Parser[Any] = rep(param)~opt(":"~tail) ^^ (x=> {println("params: " +x)}) 
    val param: Parser[Any] = """[^:][\S]*""".r 
    val tail: Parser[Any] = """.*$""".r ^^ (x=> {println("tail: " +x)}) 
    val letter: Parser[Any] = """[A-Za-z]""".r ^^ (x=> {println("letter: " +x)}) 
} 

我不太清楚w ^帽子可能会造成这种情况。希望我只是对一些小事一无所知。

+0

这是由于声明的顺序吗? '前缀'使用'尼克' – 2011-03-22 20:00:03

+0

我现在看到,是的,似乎可能是问题的根源。 – ReferentiallySeethru 2011-03-22 20:18:08

回答

3

lazy val值根据需要填充; val值将按照您指定的顺序填充。使用解析器,早期的条目指的是后来不存在的条目。所以他们最好是lazy valdef(哪一个取决于解析器; packrat解析器喜欢lazy val,而其他人通常假设def,但我不确定他们是否需要它)。

0

抓住用下面的代码除外:

try { 
    //your code here 
} catch { 
    case err: ExceptionInInitializerError => err.getCause.printStackTrace 
} 

这将帮助你找到异常的原因。