rex 和 racc (一) 初步安装和使用

 

 

    使用ruby的朋友会发现rex/racc这样的应用,他们是纯ruby实现的lex/yacc.

    如果你有这样的任务,需要在ruby中解析一些代码.如果你熟悉 lex/yacc,那么首先的想法是,能否用ruby中的rex/racc来实现。

   

    那么首先一点是,如何搭建这样的环境呢?

   目前网络上这样的资源比较少,基本上要靠自己摸索之后,才能很好的使用。

  

   首先:安装rex

   http://raa.ruby-lang.org/project/rex/  中下载http://homepage1.nifty.com/arima/ruby/rex-1.0rc1.tar.gz

  然后解包,

  运行 里面的setup.rb

    ruby setup.rb config
   ruby  setup.rb show
   ruby  setup.rb setup
   ruby    setup.rb install

他会安装rex到相应的目录, 默认的会产生rex.cmd.

 建议将它删除, 将同目录下的rex 更改成rex.bat 并且将它的头和尾加入下面的代码(完整修改之后的内容如下):

@echo off
@if not "%~d0" == "~d0" goto WinNT
/usr/local/bin/ruby -x "/usr/local/bin/erb.bat" %1 %2 %3 %4 %5 %6 %7 %8 %9
@goto endofruby
:WinNT
"%~dp0ruby" -x "%~f0" %*
@goto endofruby
#!/usr/local/bin/ruby
#
# rex.rb
#
#   Copyright (c) 2005-2006 ARIMA Yasuhiro <arima.yasuhiro@nifty.com>
#
#   This program is free software.
#   You can distribute/modify this program under the terms of
#   the GNU LGPL, Lesser General Public License version 2.1.
#   For details of LGPL, see the file "COPYING".
#

## ---------------------------------------------------------------------

require 'rex/rexcmd'

RexCmd.new.run


__END__
:endofruby

 

这样,我们的rex.bat 就类似于 irb.bat等默认的bat。

   其次,安装racc

  http://i.loveruby.net/en/projects/racc/ 

  下载 上面的 -- Download (.tar.gz)  

  解压,然后运行:

  ruby setup.rb config
  ruby  setup.rb setup
  ruby  setup.rb install

  就可以了,不建议下载svn 里面的代码然后手工编译,我目前试过编译可以通过,但运行有错误。

  在ruby/bin目录下,创建一个racc.bat

  内容为:

  "%~dp0ruby"  "%~dp0racc" %*

  当然也可以使用上面的技巧,直接修改racc文件。

 

  最后,运行简单的例子(rex/racc的组合运行)

   创建一个text.rex文件

  1. require 'text.rex' 
  2. class Text
  3. macro
  4.     BLANKS  /s+
  5.     DIGITS  /d+
  6.     LETTERS [a-zA-Z]+
  7. rule
  8.     {BLANKS}
  9.     {LETTERS} { puts :ID , "#{text}"; [ :ID, text] }
  10.     {DIGITS} { puts  "#{text}"; [ :NUMBER, text.to_i ] }
  11.     .|/n { puts  "#{text}"; [ text, text ] }
  12. inner
  13. end

      创建text.y文件

    

  1. #
  2. # A simple calculator, version 3.
  3. #
  4. class Text
  5.   prechigh
  6.     nonassoc UMINUS
  7.     left '*' '/'
  8.     left '+' '-'
  9.   preclow
  10.   options no_result_var
  11. rule
  12.   target  : exp
  13.           | /* none */ { 0 }
  14.   exp     : exp '+' exp { val[0] + val[2] }
  15.           | exp '-' exp { val[0] - val[2] }
  16.           | exp '*' exp { val[0] * val[2] }
  17.           | exp '/' exp { val[0] / val[2] }
  18.           | '(' exp ')' { val[1] }
  19.           | '-' NUMBER  =UMINUS { -(val[1]) }
  20.           | NUMBER
  21. end
  22. ---- header ----
  23. #
  24. # generated by racc
  25. #
  26. require 'text.rex.rb'
  27. ---- inner ----
  28. ---- footer ----
  29. puts 'sample calc'
  30. puts '"q" to quit.'
  31. calc = Text.new
  32. while true
  33.   print '>>> '; $stdout.flush
  34.   str = $stdin.gets.strip
  35.   break if /q/i === str
  36.   begin
  37.     p calc.scan_str(str)
  38.   rescue ParseError
  39.     puts 'parse error'
  40.   end
  41. end

     运行:

rex text.rex
上面会产生text.rex.rb
racc text.y
会产生text.tab.rb

运行:
ruby text.tab.rb 就可以了

在命令行输入: 1+2  会输出3 的。

如:

D:/dev_tool/ruby>ruby text.tab.rb
sample calc
"q" to quit.
>>> 1+2
1
+
2
3
>>>

 

 (熟悉lex/yacc的朋友,看上面的代码应该很快,后面我会陆续加入新的文章来描述这一块内容)。

如果查看text.y中,会发现它包含了 text.rex.rb的代码. 呵呵,从而rex/racc就可以组合在一块了.

 

如果用ruby1.9的,估计会出现这样的错误:

undefined method `collect' for #<String:0xc36cd8> (NoMethodError)

那找到相应的行,将option 从string更改成array就可以了。

比如:C:/ruby-1.9.1/usr/local/lib/ruby/site_ruby/1.9.1/rex/rexcmd.rb

包含:

 

 

 

  1. OPTIONS  =  <<-EOT
  2. o -o --output-file <outfile>  file name of output [<filename>.rb]
  3. o -s --stub             - append stub code for debug
  4. o -i --ignorecase       - ignore char case
  5. o -C --check-only       - syntax check only
  6. o -  --independent      - independent mode
  7. o -d --debug            - print debug information
  8. o -h --help             - print this message and quit
  9. o -  --version          - print version and quit
  10. o -  --copyright        - print copyright and quit
  11. EOT

而在ruby1.9出错,那么我们可以将上面这块代码修改成:

 



  1. oldOptions  =  <<-EOT
  2. o -o --output-file <outfile>  file name of output [<filename>.rb]
  3. o -s --stub             - append stub code for debug
  4. o -i --ignorecase       - ignore char case
  5. o -C --check-only       - syntax check only
  6. o -  --independent      - independent mode
  7. o -d --debug            - print debug information
  8. o -h --help             - print this message and quit
  9. o -  --version          - print version and quit
  10. o -  --copyright        - print copyright and quit
  11. EOT
  12. OPTIONS  = []
  13. oldOptions.each_line do |line|
  14.      OPTIONS.push(line)
  15. end

 

 

  

  



    

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值