从Java走进Scala构建计算器DSL文档格式.docx

上传人:b****6 文档编号:15834692 上传时间:2022-11-16 格式:DOCX 页数:11 大小:22.02KB
下载 相关 举报
从Java走进Scala构建计算器DSL文档格式.docx_第1页
第1页 / 共11页
从Java走进Scala构建计算器DSL文档格式.docx_第2页
第2页 / 共11页
从Java走进Scala构建计算器DSL文档格式.docx_第3页
第3页 / 共11页
从Java走进Scala构建计算器DSL文档格式.docx_第4页
第4页 / 共11页
从Java走进Scala构建计算器DSL文档格式.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

从Java走进Scala构建计算器DSL文档格式.docx

《从Java走进Scala构建计算器DSL文档格式.docx》由会员分享,可在线阅读,更多相关《从Java走进Scala构建计算器DSL文档格式.docx(11页珍藏版)》请在冰豆网上搜索。

从Java走进Scala构建计算器DSL文档格式.docx

8.private[calcdsl]caseclassUnaryOp(operator:

String,arg:

Expr)extendsExpr

9.private[calcdsl]caseclassBinaryOp(operator:

String,left:

Expr,right:

Expr)

10.extendsExpr

11.

12.}

……对此我们可以提供类似解释器的行为,它能最大限度地简化数学表达式……

清单2.后端(解释器)

5.objectCalc

6.{

7.defsimplify(e:

Expr):

Expr={

8.//firstsimplifythesubexpressions

9.valsimpSubs=ematch{

10.//Askeachsidetosimplify

11.caseBinaryOp(op,left,right)=>

BinaryOp(op,simplify(left),simplify(right))

12.//Asktheoperandtosimplify

13.caseUnaryOp(op,operand)=>

UnaryOp(op,simplify(operand))

14.//Anythingelsedoesn'

thavecomplexity(nooperandstosimplify)

15.case_=>

e

16.}

17.

18.//nowsimplifyatthetop,assumingthecomponentsarealreadysimplified

19.defsimplifyTop(x:

Expr)=xmatch{

20.//Doublenegationreturnstheoriginalvalue

21.caseUnaryOp("

-"

UnaryOp("

x))=>

x

22.

23.//Positivereturnstheoriginalvalue

24.caseUnaryOp("

+"

x)=>

25.

26.//Multiplyingxby1returnstheoriginalvalue

27.caseBinaryOp("

*"

x,Number

(1))=>

28.

29.//Multiplying1byxreturnstheoriginalvalue

30.caseBinaryOp("

Number

(1),x)=>

31.

32.//Multiplyingxby0returnszero

33.caseBinaryOp("

x,Number(0))=>

Number(0)

34.

35.//Multiplying0byxreturnszero

36.caseBinaryOp("

Number(0),x)=>

37.

38.//Dividingxby1returnstheoriginalvalue

39.caseBinaryOp("

/"

40.

41.//Dividingxbyxreturns1

42.caseBinaryOp("

x1,x2)ifx1==x2=>

Number

(1)

43.

44.//Addingxto0returnstheoriginalvalue

45.caseBinaryOp("

46.

47.//Adding0toxreturnstheoriginalvalue

48.caseBinaryOp("

49.

50.//Anythingelsecannot(yet)besimplified

51.casee=>

52.}

53.simplifyTop(simpSubs)

54.}

55.

56.defevaluate(e:

Expr):

Double=

57.{

58.simplify(e)match{

59.caseNumber(x)=>

60.caseUnaryOp("

-(evaluate(x))

61.caseBinaryOp("

x1,x2)=>

(evaluate(x1)+evaluate(x2))

62.caseBinaryOp("

(evaluate(x1)-evaluate(x2))

63.caseBinaryOp("

(evaluate(x1)*evaluate(x2))

64.caseBinaryOp("

(evaluate(x1)/evaluate(x2))

65.}

66.}

67.}

68.}

……我们使用了一个由Scala解析器组合子构建的文本解析器,用于解析简单的数学表达式……

清单3.前端

7.objectArithParserextendsJavaTokenParsers

8.{

9.defexpr:

Parser[Any]=term~rep("

~term|"

~term)

10.defterm:

Parser[Any]=factor~rep("

~factor|"

~factor)

11.deffactor:

Parser[Any]=floatingPointNumber|"

("

~expr~"

)"

12.

13.defparse(text:

String)=

14.{

15.parseAll(expr,text)

17.}

18.

19.//...

20.}

21.}

……但在进行解析时,由于解析器组合子当前被编写为返回Parser[Any]类型,所以会生成String和List集合,实际上应该让解析器返回它需要的任意类型(我们可以看到,此时是一个String和List集合)。

要让DSL成功,解析器需要返回AST中的对象,以便在解析完成时,执行引擎可以捕获该树并对它执行evaluate()。

对于该前端,我们需要更改解析器组合子实现,以便在解析期间生成不同的对象。

清理语法

对解析器做的第一个更改是修改其中一个语法。

在原来的解析器中,可以接受像“5+5+5”这样的表达式,因为语法中为表达式(expr)和术语(term)定义了rep()组合子。

但如果考虑扩展,这可能会引起一些关联性和操作符优先级问题。

以后的运算可能会要求使用括号来显式给出优先级,以避免这类问题。

因此第一个更改是将语法改为要求在所有表达式中加“()”。

回想一下,这应该是我一开始就需要做的事情;

事实上,放宽限制通常比在以后添加限制容易(如果最后不需要这些限制),但是解决运算符优先级和关联性问题比这要困难得多。

如果您不清楚运算符的优先级和关联性;

那么让我大致概述一下我们所处的环境将有多复杂。

考虑Java语言本身和它支持的各种运算符(如Java语言规范中所示)或一些关联性难题(来自Bloch和Gafter提供的JavaPuzzlers),您将发现情况不容乐观。

因此,我们需要逐步解决问题。

首先是再次测试语法:

清单4.采用括号

7.//...

8.

9.objectOldAnyParserextendsJavaTokenParsers

10.{

11.defexpr:

12.defterm:

13.deffactor:

14.

15.defparse(text:

16.{

17.parseAll(expr,text)

18.}

19.}

20.objectAnyParserextendsJavaTokenParsers

21.{

22.defexpr:

Parser[Any]=(term~"

~term)|(term~"

~term)|term

23.defterm:

Parser[Any]=(factor~"

~factor)|(factor~"

~factor)|factor

24.deffactor:

Parser[Any]="

~>

expr<

~"

|floatingPointNumber

26.defparse(text:

27.{

28.parseAll(expr,text)

29.}

30.}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 唐诗宋词

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1