是否有一个ruby解析器生成器可以生成一个没有gem依赖的解析器?

时间:2013-04-30 13:54:49

标签: ruby parsing antlr peg

为了制作DSL我已经向后兼容 ruby​​ 1.8,我需要对源字符串进行一些(相对简单的)解析。我可能直接使用字符串munging,但为了将来的可维护性,我想先调查一下,看看使用正确的解析器生成器需要什么。

然而,这个DSL的作用对我可以使用的 ruby​​ 宝石造成了不同寻常的限制。 DSL是 Xcode 项目的一部分,该项目随 CocoaPods 一起发布,而 CocoaPods 并非真正关于管理 ruby​​ 依赖项在构建环境中。

这意味着,我的 ruby​​ DSL实际上仅限于预装在 Mac OS X 10.8 上的宝石。

SO ,我的问题:是否有 ruby​​ 解析器生成器生成“独立” ruby​​ 代码作为其最终输出?意味着 ruby​​ 代码不require任何不属于核心 ruby​​ 的内容?

我已经查看了 ANTLR for Ruby 的(稀疏)文档,但它(可以理解)并没有解决我的问题。从我对 treetop 的快速一瞥中,它似乎确实使用捆绑为宝石的支持包。

1 个答案:

答案 0 :(得分:1)

进一步搜索后,我遇到了 rexical gem,它本身是 rex 的重命名和维护版本。这是一个老式的词法分析器生成器,只依赖于 racc / parser ,它已经成为 ruby​​-core 的一部分足够长,以至于我不需要担心它。

文档很少,但有足够的博客文章涉及到我能够得到我需要工作的主题。

如果您对此感到好奇,请阅读此示例 .rex 规范:

require 'generator'

class OptionSpecsLexer
rules
  \d+(\.\d*)            { [:number, text] }
  \w+:                  { [:syntax_hash_key, ":#{text[0, text.length - 1]} =>"] }
  \:\w+                 { [:symbol, text] }
  \w+\(                 { [:funcall_open_paren, text] }
  \w+                   { [:identifier, text] }
  \"(\\.|[^\\"])*\"     { [:string, text] }
  =>                    { [:rocket, text] }
  ,                     { [:comma, text] }
  \{                    { [:open_curly, text] }
  \}                    { [:close_curly, text] }
  \(                    { [:open_paren, text] }
  \)                    { [:close_paren, text] }
  \[                    { [:close_square, text] }
  \]                    { [:close_square, text] }
  \\\s+                 { }
  \n                    { [:eol, text] }
  \s+                   { }

inner

  def enumerate_tokens
    Generator.new { |token|
      loop {
        t = next_token
        break if t.nil?
        token.yield(t)
      }
    }
  end

  def normalize(source)
    scan_setup source
    out = ""
    enumerate_tokens.each do |token|
      out += ' ' + token[1]
    end
    out
  end

end

此词法分析器理解足够的 ruby​​ 语法来预处理在我的 vMATCodeMonkey DSL中编写的规范,将新的关键字样式哈希键语法替换为旧的火箭操作符语法。 [这样做是为了允许 vMATCodeMonkey 在未更新的 Mac OS X 10.8 上工作,该版本仍附带已弃用的 ruby​​ 版本。 / p>