快速业务通道

一个简单的语言的语法(三):做些小调整,并将生成目标换到CSharp2 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-14
码里用的lookahead的个数(*):

Ruby代码

1.def check_lookaheads(file) 2. lookaheads = open file, ''r'' do |f| 3. ret = [] 4. f.readlines.grep(/^\s+(.+\.la\((\d+)\).+)$/i) do 5. ret << "#{$2}: #{$1}" 6. end 7. ret 8. end 9.end 10. 11.if __FILE__ == $0 12. la = check_lookaheads ARGV[0] || ''JerryParser.cs'' 13. puts ''Lookaheads:'', la, '''' 14. puts "Non-LL(1)''s:", la.select { |l| ?1 != l[0] } 15.end

一个简单的语言的语法(三):做些小调整,并将生成目标换到CSharp2(3)

时间:2011-10-07 javaeye RednaxelaFX

明白了这个道理,就应该尽量将重写规则中的各个根节点设计成能直接区分的。

实际上不只是树的语法,在编程语言的源码的语法设计上也是一样:最容易解析的语法是每条规则都 以特殊的token开头的语法,例如说声明变量就以var关键字开头,声明函数就以function关键字开头等。 这样能保证语法只需要1个lookahead。而类似C的语法对解析器来说实在算不上友善……|||

(*:ANTLR在遇到比较复杂的判断条件时不会直接在规则对应的方法里调用input.LA(n),而是会生成 一个DFA类来计算应该走的分支。上面的Ruby脚本不检查这个状况。)

其次,所有虚构token都添加了一些信息在后面。例如说原本一元负号的规则是:

Java代码

MINUS primaryExpression
  -> ^( UNARY_MINUS primaryExpression )

则UNARY_MINUS这个虚构token将不包含任何文字、位置信息。因为MINUS原本携带的位置信息已经丢失 了,所以如果后续处理中需要知道这个表达式的位置就没办法得到。

改写为这样:

Java代码

MINUS primaryExpression
  -> ^( UNARY_MINUS[$MINUS] primaryExpression )

则使得UNARY_MINUS继承MINUS匹配时的文字、位置等属性,解决了前面的问题。

除此之外,原本写在program规则里的嵌入动作也去掉了。之前写在那里主要是为了在parser内输出 AST的字符串表示,只是演示用。

修改后的完整语法如下:

C#代码

1.grammar Jerry; 2. 3.options { 4. language = CSharp2; 5. output = AST; 6. ASTLabelType = CommonTree; 7.} 8. 9.tokens { 10. // imaginary tokens 11. SIMPLE_VAR_DECL; 12. SIMPLE_VAR_DECL_INIT; 13. ARRAY_VAR_DECL; 14. ARRAY_VAR_DECL_INIT; 15. ARRAY_LITERAL; 16. SIMPLE_VAR_ACCESS; 17. ARRAY_VAR_ACCESS; 18. UNARY_MINUS; 19. BLOCK; 20. EMPTY_BLOCK; 21. EXPR_STMT; 22.} 23. 24.// parser rules 25. 26.program : statement+ EOF! 27. ; 28. 29.statement 30. : expressionStatement 31. | variableDeclaration 32. | blockStatement 33. | ifStatement 34. | whileStatement 35. | breakStatement 36. | readStatement 37. | writeStatement 38. ; 39. 40.expressionStatement 41. : expression SEMICOLON 42. - > ^( EXPR_STMT[$expression.start, "ExprStmt"] expression ) 43. ; 44. 45.variableDeclaration 46. : typeSpecifier 47. ( id1=Identifier 48. ( ( -> ^( SIMPLE_VAR_DECL[$id1, "VarDecl"] ^( typeSpecifier ) $id1 ) ) 49. | ( EQ expression 50. -> ^( SIMPLE_VAR_DECL_INIT[$id1, "VarDeclInit"] ^( typeSpecifier ) $id1 expression ) ) 51. | ( ( LBRACK Integer RBRACK )+ 52. -> ^( ARRAY_VAR_DECL[$id1, "VarDecl"] ^( typeSpecifier Integer+ ) $id1 ) ) 53. | ( ( LBRACK Integer RBRACK )+ EQ arrayLiteral 54. -> ^( ARRAY_VAR_DECL_INIT[$id1, "VarDeclInit"] ^( typeSpecifier Integer+ ) $id1 arrayLiteral ) ) 5

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站: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号