2013-10-04 31 views
4

我知道defvallazy val之間的區別,但我不確定它們對於Parser Combinators的影響。我見過的所有示例包含這樣的代碼:def或val或lazy val的語法規則?

def statement: Parser[Statement] = 
    ifStatement | 
    whileStatement | 
    expressionStatement | ... 

從幾個實驗我已經做了,似乎vallazy val工作爲好,但我不知道是否有這樣的情況,他們將無法正常工作再次,像遞歸或定位解析器或whatnot。

請賜教!

回答

2

如果您看the api documentation,解析器構建方法和運算符是使用名稱參數然後cached using lazy val實現的。

這就是說,你仍然要小心初始化的順序。下面的代碼將導致空引用異常:

val as = a.* 
val a = "a" 

但是下面是好的(因爲參數~是名):

val as = "a" ~ a.* 
val a = "a" 

lazy眼前的一切將「幫助',但是很吵。性能不應該是一個大問題,因爲通常你只想要初始化語法一次。 def對於每個被引用的點,表達式都將被初始化一次。

你可以是一個有點聰明,消除了使用塊語法您的「次要」生產水暖:

lazy val addExpr = { 
    val add = expr ~ "+" ~ expr 
    val sub = expr ~ "-" ~ expr 
    add | sub 
} 
+0

好了,這樣我就可以用'def'無處不在,不必過於擔心性能? – fredoverflow

+0

從本質上講,但是您應該注意,每次使用它時都不會重新初始化語法。當使用[packrat解析器](http://www.scala-lang.org/api/current/index.html#scala.util.parsing.combinator.PackratParsers)作爲解析器的概念時,也有關於memoization的含義身份變得重要,但除非性能成爲問題,否則我不會擔心。 –