rex 和 racc (二) 去掉注释的内容

    经过这几天的使用,发现需要去掉被解析文件里面的注释。这在lex & yacc里面是非常常见的,

   但是在rex&racc 里面类似的修改就会发现行不通。

   既然行不通,首先想到的就是看看网上有没有这样的解决方案。 但遗憾的是没有。

   没办法,只能靠自己了。 经过摸索,终于弄清楚了怎样添加了。

    现贴出来,供大家参考。

   

     我们采用一个例子,它的整体代码打包到这里(http://download.csdn.net/source/860402)。

      rex 文法里面可以添加状态。 (具体的rex文件规范后面贴出来) 文件 test.rex

     

  1. class Test
  2. macro
  3.     BLANKS  [/ /t/f/r]+
  4.     DIGITS  /d+
  5.     LETTERS [a-zA-Z]+
  6.     VARAIBLE [_a-zA-Z][_a-zA-Z0-9]* 
  7.     REMIN  ///*
  8.     REMOUT /*//
  9. rule
  10.          {BLANKS}  
  11.          {REMIN} { state = :REM ; [:REM_IN, text] } 
  12.          :REM  {REMOUT}   { state = nil ; [:REM_OUT, text] } 
  13.          :REM  (?m:.+?)(?={REMOUT})    { [:COMMENT, text] }
  14.          /n      {          [:NEW_LINE, text]     }                            
  15.          . { [:TEXT,text] } 
  16. inner
  17. end

这段文法是可以解析注释。 它忽略了空格(注意,换行符做处理了)。

我们添加相应的racc文法,文件 test.y
  

  1. class Test
  2. rule  
  3.   TEST_DATA : SIGNLE_TEST_DATA  
  4.              | TEST_DATA SINGLE_TEST_DATA             
  5.              |
  6.              
  7.              
  8.   SINGLE_TEST_DATA : COMMENT_STATE { print "<<<Im in comment>>>" }
  9.                     | TEXT         { print val[0] } 
  10.                     | NEW_LINE     { print "/n" }
  11.                                      
  12.   COMMENT_STATE :  REM_IN  COMMENT_CONTENT  REM_OUT   
  13.     
  14.   COMMENT_CONTENT:  COMMENT         
  15.                    |
  16.                    
  17. end
  18. ---- header ----
  19. # -*- coding: gb2312 -*-
  20. #
  21. # generated by racc
  22. #
  23. require 'test.rex'
  24. ---- inner ----
  25. ---- footer ----
  26. def parse_Test(strFileInput)
  27.     puts 'parsing text...'
  28.     resourceParser = Test.new  
  29.   str = File.open(strFileInput).read    
  30.   begin
  31.     resourceParser.scan_str(str)
  32.   rescue ParseError => ex
  33.     puts 'parse error'
  34.     raise ex    
  35.   end
  36. end

   这样我们就处理了注释, 同时也忽略了空格。
但是,如果我们在真正做解析的时候发现,我们需要规范我们的注释的位置,否则每个文法的地方都需要加入注释。
那我们能否直接将注释让它象空格一样忽略呢?
在lex&yacc里面我们很容易的就忽略它了,那在rex&racc里面是否也可以呢?

注意到上面的空格忽略,它不添加任何的action。但是我们注释需要变更当前的state。
能否将上面的rex文件直接更改为
 {REMIN} { state = :REM ;} 呢?

你可以试一下,会马上发现出现错误 next_token() returned Symbol (must be Array[2])

难道不行吗? 我们可以看看rex产生的文件 test.rex.rb 里面,发现它 @rex_tokens.push action { state = :REM ;  }
而action是一个method,它直接运行block里面的语句,然后将返回值保存到@rex_tokes的数组。

哦,如果看到这里,估计你就可以直接修改next_token 让它不返回不是数组的token。呵呵
在test.rex 文件里面的inner段加入:
class Test
....
inner
  def next_token    
     nextToken = nil
     while true  do
       nextToken = nil
       break if @rex_tokens.empty?
       nextToken = @rex_tokens.shift                                   
       if  nextToken.is_a? Array
          break
       end
     end 
     nextToken    
  end
end

这样就发现不会报错,并且可以任意忽略注释。

经过这样的修改,我们发现和使用lex/yacc一样了。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值