新手问题 如何理解 Ripper.sexp 输出信息

ceclinux-github · 2017年11月03日 · 最后由 mizuhashi 回复于 2017年11月03日 · 1569 次阅读

我想要了解下 Ruby parser 相关的内容,发现了 Ripper 这个库,但是它的输出很难看懂,比如说官方的例子

require 'ripper'
require 'pp'

pp Ripper.sexp('def hello(world) "Hello, #{world}!"; end')
  #=> [:program,
       [[:def,
         [:@ident, "hello", [1, 4]],
         [:paren,
          [:params, [[:@ident, "world", [1, 10]]], nil, nil, nil, nil, nil, nil]],
         [:bodystmt,
          [[:string_literal,
            [:string_content,
             [:@tstring_content, "Hello, ", [1, 18]],
             [:string_embexpr, [[:var_ref, [:@ident, "world", [1, 27]]]]],
             [:@tstring_content, "!", [1, 33]]]]],
          nil,
          nil,
          nil]]]]

能猜出一些,但是全部了解还是有困难(比如说string_embexpr),希望能提供一些相关的文档,谢谢

Just Google it

jasl 回复

我例子给的不太好,这里面的symbol似乎都是Ripper::EVENTS里的,我想最好能有对这些Events的文档(类似于表格),而且一个一个查的话也不全能找到。

Ripper::EVENTS
[:BEGIN, :END, :alias, :alias_error, :aref, :aref_field,
 :arg_ambiguous, :arg_paren, :args_add, :args_add_block, :args_add_star,
 :args_new, :array, :assign, :assign_error, :assoc_new,
 :assoclist_from_args, :bare_assoc_hash, :begin, :binary, :block_var,
 :block_var_add_block, :block_var_add_star, :blockarg, :bodystmt,
 :brace_block, :break, :call, :case, :class, :class_name_error, :command,
 :command_call, :const_path_field, :const_path_ref, :const_ref, :def,
 :defined, :defs, :do_block, :dot2, :dot3, :dyna_symbol, :else, :elsif,
 :ensure, :excessed_comma, :fcall, :field, :for, :hash, :if, :if_mod,
 :ifop, :lambda, :magic_comment, :massign, :method_add_arg,
 :method_add_block, :mlhs_add, :mlhs_add_star, :mlhs_new, :mlhs_paren,
 :module, :mrhs_add, :mrhs_add_star, :mrhs_new, :mrhs_new_from_args,
 :next, :opassign, :operator_ambiguous, :param_error, :params, :paren,
 :parse_error, :program, :qwords_add, :qwords_new, :redo, :regexp_add,
 :regexp_literal, :regexp_new, :rescue, :rescue_mod, :rest_param, :retry,
 :return, :return0, :sclass, :stmts_add, :stmts_new, :string_add,
 :string_concat, :string_content, :string_dvar, :string_embexpr,
 :string_literal, :super, :symbol, :symbol_literal, :top_const_field,
 :top_const_ref, :unary, :undef, :unless, :unless_mod, :until, :until_mod,
 :var_alias, :var_field, :var_ref, :void_stmt, :when, :while, :while_mod,
 :word_add, :word_new, :words_add, :words_new, :xstring_add,
 :xstring_literal, :xstring_new, :yield, :yield0, :zsuper, :CHAR,
 :__end__, :backref, :backtick, :comma, :comment, :const, :`cvar, :embdoc,
 :embdoc_beg, :embdoc_end, :embexpr_beg, :embexpr_end, :embvar, :float,
 :gvar, :heredoc_beg, :heredoc_end, :ident, :ignored_nl, :int, :ivar, :kw,
 :label, :lbrace, :lbracket, :lparen, :nl, :op, :period, :qwords_beg,
 :rbrace, :rbracket, :regexp_beg, :regexp_end, :rparen, :semicolon, :sp,
 :symbeg, :tlambda, :tlambeg, :tstring_beg, :tstring_content,
 :tstring_end, :words_beg, :words_sep]
``

这些都是 Ruby 的文法,恐怕你得有 YACC 的经验才能看懂了...

https://github.com/whitequark/parser/blob/master/lib/parser/ruby24.y

不如看 whitequark 的 parser 或者 seattlerb 的 ruby_parser,ripper 的比较低级

ceclinux-github 关闭了讨论。 11月03日 21:40
需要 登录 后方可回复, 如果你还没有账号请 注册新账号