语法规则的 def 或 val 或惰性 val ? [英] def or val or lazy val for grammar rules?

查看:44
本文介绍了语法规则的 def 或 val 或惰性 val ?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一般知道 defvallazy val 之间的区别,但我不确定它们的影响到解析器组合器.我见过的所有例子都包含这样的代码:

I know the difference between def and val and lazy val in general, but I'm not sure about their repercussions when it comes to Parser Combinators. All examples I have seen contain code like this:

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

从我做过的一些实验来看,似乎 vallazy val 也能工作,但我不确定是否有它们不会的情况不再工作,例如递归或定位解析器或诸如此类.

From a few experiments I have done, it seems val and lazy val work as well, but I'm not sure if there are cases where they wouldn't work anymore, like recursion or positioned parsers or whatnot.

请赐教!

推荐答案

如果你看一下 api 文档,解析器构建方法和运算符是使用按名称参数实现的,然后是 使用lazy val缓存.

If you look at the api documentation, the parser-building methods and operators are implemented using by-name parameters which are then cached using lazy val.

话虽如此,您仍然需要注意初始化的顺序.以下代码将导致空引用异常:

That being said, you still have to be careful about order of initialization. The following code will result in a null reference exception:

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

但是,以下内容很好(因为 ~ 的参数是按名称):

However the following is fine (because the argument to ~ is by-name):

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

lazy 放在一切前面会有帮助",但会很吵.性能应该不是什么大问题,因为通常您只想初始化一次语法.def 表达式将针对它们引用的每个点初始化一次.

Putting lazy in front of everything will 'help', but is noisy. Performance should not be a big deal, as generally you will only want to initialize the grammar once. def expressions will be initialized once for each point they are referenced.

您可以聪明一点,使用块语法为您的次要"制作消除管道:

You can be a bit clever and eliminate plumbing for your 'minor' productions using block syntax:

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

这篇关于语法规则的 def 或 val 或惰性 val ?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆