经过进一步搜索,我发现了 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 编写的规范,将新的 keyword 样式的哈希键语法替换为旧的 rocket operator 语法。 [这样做是为了让 vMATCodeMonkey 可以在未更新的 Mac OS X 10.8 上工作,该版本仍然带有已弃用的 ruby 版本。]