免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1263 | 回复: 1
打印 上一主题 下一主题

递归下降解析器模块Parse::RecDescent的例子 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-08-28 17:15 |只看该作者 |倒序浏览
看过编译原理的应该能看懂这个简单的网上例子。我试了下,可以运行。
  1. #!/usr/bin/perl -w
  2. use strict;
  3. use Parse::RecDescent;
  4. use Data::Dumper;

  5. use vars qw(%VARIABLE);

  6. # Enable warnings within the Parse::RecDescent module.

  7. $::RD_ERRORS = 1; # Make sure the parser dies when it encounters an error
  8. $::RD_WARN   = 1; # Enable warnings. This will warn on unused rules &c.
  9. $::RD_HINT   = 1; # Give out hints to help fix problems.

  10. my $grammar = <<'_EOGRAMMAR_';

  11. # Terminals (macros that can't expand further)
  12. #

  13. OP       : m([-+*/%])      # Mathematical operators
  14. INTEGER  : /[-+]?\d+/      # Signed integers
  15. VARIABLE : /\w[a-z0-9_]*/i # Variable

  16. expression : INTEGER OP expression
  17.           { return main::expression(@item) }
  18.           | VARIABLE OP expression
  19.           { return main::expression(@item) }
  20.           | INTEGER
  21.           | VARIABLE
  22.           { return $main::VARIABLE{$item{VARIABLE}} }

  23. print_instruction  : /print/i expression
  24.                   { print $item{expression}."\n" }
  25. assign_instruction : VARIABLE "=" expression
  26.                   { $main::VARIABLE{$item{VARIABLE}} = $item{expression} }

  27. instruction : print_instruction
  28.            | assign_instruction

  29. startrule: instruction(s /;/)

  30. _EOGRAMMAR_

  31. sub expression {
  32. shift;
  33. my ($lhs,$op,$rhs) = @_;
  34. $lhs = $VARIABLE{$lhs} if $lhs=~/[^-+0-9]/;
  35. return eval "$lhs $op $rhs";
  36. }

  37. my $parser = Parse::RecDescent->new($grammar);


  38. print "a=2\n";             $parser->startrule("a=2");
  39. print "a=1+3\n";           $parser->startrule("a=1+3");
  40. print "print 5*7\n";       $parser->startrule("print 5*7");
  41. print "print 2/4\n";       $parser->startrule("print 2/4");
  42. print "print 2+2/4\n";     $parser->startrule("print 2+2/4");
  43. print "print 2+-2/4\n";    $parser->startrule("print 2+-2/4");
  44. print "a = 5 ; print a\n"; $parser->startrule("a = 5 ; print a");
  45. exit;
复制代码

求职 : 软件工程师
论坛徽章:
3
程序设计版块每日发帖之星
日期:2015-10-07 06:20:00程序设计版块每日发帖之星
日期:2015-12-13 06:20:00程序设计版块每日发帖之星
日期:2016-05-05 06:20:00
2 [报告]
发表于 2016-08-29 02:56 |只看该作者
这个模块的作者在澳洲演讲,门票价格还挺贵。看样很多人喜欢这个模块。

这个模块也算是一个巅峰之作了。我测试过,非常慢。

不过我写了一个程序,专门用于定制语法,解析代码。

不但内嵌代码,还能直接返回相应的数据结构。

语言本来是非常精确的东西,不知道此类模块返回的大都是哈希+数组类的数据结构。
哈希本来会丧失顺序。虽然有可选的输出选项。但感觉用的不方便。

Perl6 也是做这个的,但速度也很慢。不知道 Perl6 为什么定义那么复杂的语法。让 Perl6 的速度一直提不上来。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP