作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是函数式编程的新手,想知道如何在不使用变量赋值的情况下以纯函数方式解决在上下文无关语法中计算可空非终结符集的问题。
可空非终结符是直接产生空的非终结符,例如 A::= 或具有包含可空非终结符的主体,例如 A::= B C D,其中所有 B C 和 D 都为空。
我在 Scala 中使用以下定义来定义语法:
case class Grammar(name:String, startSymbol:Nonterminal, rules:List[Rule])
case class Rule(head: Nonterminal, body:List[Symbol])
abstract class Symbol
case class Terminal(c:Char) extends Symbol
case class Nonterminal(name:String) extends Symbol
一个基本算法是收集所有直接可为空的非终结符并将它们放在一个集合中。然后在每次迭代中尝试确定哪些生产规则具有所有可为空的非终结符在他们的身上。这些非终结符将被添加到集合中,直到没有新的非终结符被添加到集合中放。
我已经在 Scala 中实现了这个过程:
def getNullableNonterminals(grammar:Grammar) = {
var nieuw : Set[Nonterminal] = (for(Rule(head, Nil) <- grammar.rules) yield head) (collection.breakOut)
var old = Set[Nonterminal]()
while(old != nieuw) {
old = nieuw
for{
Rule(head, symbols) <- grammar.rules
if symbols.length > 0
if symbols.forall( s => s.isInstanceOf[Nonterminal] && old.contains(s.asInstanceOf[Nonterminal]))
} nieuw = nieuw + head
}
nieuw
}
虽然代码比等效的 Java 版本短得多,但它使用了变量。有什么建议么以函数式风格重写这段代码?
最佳答案
下面是一个更惯用的 Scala 解决方案:
object Algorithm {
def getNullableNonterminals(grammar:Grammar) = {
loop(grammar, Set())
}
@tailrec
private def loop(grammar: Grammar, nullablesSoFar: Set[Nonterminal]): Set[Nonterminal] = {
val newNullables = generateNew(grammar, nullablesSoFar)
if (newNullables.isEmpty)
nullablesSoFar //no new nullables found, so we just return the ones we have
else
loop(grammar, nullablesSoFar ++ newNullables) //add the newly found nullables to the solution set and we keep going
}
private def generateNew(grammar: Grammar, nullableSoFar: Set[Nonterminal]) = {
for {
Rule(head, body) <- grammar.rules
if !nullableSoFar.contains(head)
if body.forall(isNullable(_, nullableSoFar))
} yield head
}
//checks if the symbol is nullable given the current set of nullables
private def isNullable(symbol: Symbol, provenNullable: Set[Nonterminal]) = symbol match {
case Terminal(_) => false
case x@Nonterminal(_) => provenNullable.contains(x)
}
}
while 语句被替换为递归函数 - loop
。此外,避免使用 isInstanceOf
- 模式匹配更适合这种情况。
小观察 - 使 Symbol 类密封
,因为这可以强制警告模式匹配中的缺失案例。
关于scala - 以函数式方式计算文法的可空非终结符(最好在 Scala 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14427899/
我已经为此苦苦挣扎了一段时间。我创建了一个允许您打开 .TXT 文件的实用程序。这些文本文件包含 PCL(打印命令语言)。当我导入一个新文件时,它被\0(NULL 终止符)截断了。因为 PCL 文件随
我是一名优秀的程序员,十分优秀!