面向Java开发人员的Scala指南 - 构建计算器,第2部分 - 编程入门网
| "-"~term)
def term : Parser[Any] = factor ~ rep("*"~factor | "/"~factor)
def factor : Parser[Any] = floatingPointNumber | "("~expr~")"
def parse(text : String) =
{
parseAll(expr, text)
}
}
def parse(text : String) =
{
val results = ArithParser.parse(text)
System.out.println("parsed " + text + " as " + results + " which is a type "
+ results.getClass())
}
// ...
}
}
BNF 实际上被一些解析器组合子语法元素替换:空格被替换为 ~ 方法(表明一个序列),重复被替换为 rep 方法,而选择则仍然用 | 方法来表示。文字字符串是标准的文字字符串。 从两个方面可以看到这种方法的强大之处。首先,该解析器扩展 Scala 提供的 JavaTokenParsers 基类(后者本身又继承其他基类,如果我们想要一种与 Java 语言的语法概念不那么严格对齐的语言的话),其次,使用 floatingPointNumber 预设的组合子来处理解析一个浮点数的细节。 这种特定的(一个中缀计算器的)语法很容易使用(这也是在那么多演示稿和文章中看到它的原因),为它手工构建一个解析器也不困难,因为 BNF 语法与构建解析器的代码之间的紧密关系使我们可以更快、更容易地构建解析器。 解析器组合子概念入门 为了理解其中的原理,我们必须简要了解解析器组合子的实现。实际上,每个 “解析器” 都是一个函数或一个 case 类,它接收某种输入,并产生一个 “解析器”。例如,在最底层,解析器组合子位于一些简单的解析器之上,这些解析器以某种输入读取元素(一个 Reader)作为输入,并生成某种可以提供更高级的语义的东西(一个 Parser): 清单 6. 一个基本的解析器
面向Java开发人员的Scala指南 - 构建计算器,第2部分(5)时间:2011-01-30 Ted Neward换句话说,Elem 是一种抽象类型,用于表示任何可被解析的东西,最常见的是一个文本字符串或流。然后,Input 是围绕那种类型的一个 scala.util.parsing.input.Reader(方括号表明 Reader 是一个泛型;如果您喜欢 Java 或 C++ 风格的语法,那么将它们看作尖括号)。然后,T 类型的 Parser 是这样的类型:它接受一个 Input,并生成一个 ParseResult,后者(基本上)属于两种类型之一:Success 或 Failure。 显然,关于解析器组合子库的知识远不止这些 — 即使 ~ 和 rep 函数也不是几个步骤就可以得到的 — 但是,这让您对解析器组合子的工作原理有基本的了解。“组合” 解析器可以提供解析概念的越来越高级的抽象(因此称为 “解析器组合子”;组合在一起的元素提供解析行为)。 我们还没有完成,是吗? 我们仍然没有完成。通过调用快速测试解析器可以发现,解析器返回的内容并不是计算器系统需要的剩余部分: 清单 7. 第一次测试失败?
这次测试会在运行时失败,因为 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |