2

In an effort to make a DSL I have written backwards-compatible with ruby 1.8 I need to do some (relatively straightforward) parsing on the source strings. I could probably do directly with string munging, but in the interest of future maintainability I wanted to investigate first to see what it would take to use a proper parser generator.

The role of this DSL, however, puts an unusual constraint on what ruby gems I can use. The DSL is part of an Xcode project that's distributed with CocoaPods, and CocoaPods is not really about managing ruby dependencies in the build environment.

What this means is, my ruby DSL is effectively restricted to the gems that ship pre-installed on Mac OS X 10.8.

SO, my question: Is there a ruby parser generator out there that generates "stand-alone" ruby code as its final output? Meaning ruby code that does not require anything that's not part of core ruby?

I have looked at the (sparse) documentation for ANTLR for Ruby, but it (understandably) does not address my question. And from my quick glimpse at treetop, it does seem to use a support package bundled as a gem.

4

1 回答 1

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​​ 版本。]

于 2013-05-03T01:35:26.327 回答