快速业务通道

面向Java开发人员的Scala指南 - 构建计算器,第2部分 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-20
| "-"~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. 一个基本的解析器

type Elem type Input = Reader[Elem] type Parser[T] = Input => ParseResult[T] sealed abstract class ParseResult[+T] case class Success[T](result: T, in: Input) extends ParseResult[T] case class Failure(msg: String, in: Input) extends ParseResult[Nothing]

面向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. 第一次测试失败?

package com.tedneward.calcdsl.test {   class CalcTest   {    import org.junit._, Assert._    // ...    @Test def parseNumber =    {     assertEquals(Number(5), Calc.parse("5"))     assertEquals(Number(5), Calc.parse("5.0"))    }   } }

这次测试会在运行时失败,因为

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号