Skip to content

Instantly share code, notes, and snippets.

@lnznt
Created January 28, 2015 00:08
Show Gist options
  • Save lnznt/e1b045f31bfd14def29b to your computer and use it in GitHub Desktop.
Save lnznt/e1b045f31bfd14def29b to your computer and use it in GitHub Desktop.
$ ruby prolog_parser.rb 'f(x,y) :- a(b(c(d,e,f),!),[1,2,X|Y])'
{:":-"=>
[{:f=>[:x, :y]},
{:a=>[{:b=>[{:c=>[:d, :e, :f]}, :!]}, {[1, 2, {nil=>:X}]=>[{nil=>:Y}]}]}]}
: お試し(その1)
$ ruby t.rb < t.rb
[[[1, 0], :on_ident, "require"], # 出力情報は[位置情報,シンボル,値]
[[1, 7], :on_sp, " "],
[[1, 8], :on_tstring_beg, "'"],
[[1, 9], :on_tstring_content, "pp"],
[[1, 11], :on_tstring_end, "'"],
[[1, 12], :on_nl, "\n"],
[[2, 0], :on_ident, "require"],
[[2, 7], :on_sp, " "],
[[2, 8], :on_tstring_beg, "'"],
[[2, 9], :on_tstring_content, "ripper"],
[[2, 15], :on_tstring_end, "'"],
[[2, 16], :on_nl, "\n"],
[[3, 0], :on_ignored_nl, "\n"],
[[4, 0], :on_ident, "pp"],
[[4, 2], :on_sp, " "],
[[4, 3], :on_const, "Ripper"],
[[4, 9], :on_period, "."],
[[4, 10], :on_ident, "lex"],
[[4, 13], :on_sp, " "],
[[4, 14], :on_gvar, "$<"],
[[4, 16], :on_period, "."],
[[4, 17], :on_ident, "read"],
[[4, 21], :on_nl, "\n"]]
: お試し(その2)
$ echo ':a' | ruby t.rb
[[[1, 0], :on_symbeg, ":"], [[1, 1], :on_ident, "a"], [[1, 2], :on_nl, "\n"]]
: お試し(その3)
$ echo ':A' | ruby t.rb
[[[1, 0], :on_symbeg, ":"], [[1, 1], :on_const, "A"], [[1, 2], :on_nl, "\n"]]
: お試し(その4)
$ echo ':":-"' | ruby t.rb
[[[1, 0], :on_symbeg, ":\""],
[[1, 2], :on_tstring_content, ":-"],
[[1, 4], :on_tstring_end, "\""],
[[1, 5], :on_nl, "\n"]]
: Racc ソースのコンパイル
$ racc -o try.rb try.ry # try.rb ができあがる
3 shift/reduce conflicts # これは「シフト/還元衝突」の警告です。ここでは無視...
require 'pp'
require 'ripper'
pp Ripper.lex $<.read
require 'pry'
obj = [:foo,1,{true=>(10..20)},"hello"]
Pry::ColorPrinter.pp obj
class HighlightParser
rule
program : { result = "" }
| program token { result << val[1] }
token : ANY
| symbol { result = color(val, GREEN) }
| ON_IDENT
| ON_CONST
| ON_TSTRING_CONTENT
| ON_TSTRING_END
| ON_SYMBEG
symbol : ON_SYMBEG ON_IDENT { result = val.join }
| ON_SYMBEG ON_CONST { result = val.join }
| ON_SYMBEG ON_TSTRING_CONTENT ON_TSTRING_END { result = val.join }
end
---- header
require 'pp'
require 'ripper'
---- inner
GREEN = 32
def parse(src)
selection = %i(on_symbeg on_ident on_const on_tstring_content on_tstring_end)
conv = -> sym { selection.include?(sym) ? sym.upcase : :ANY }
@q = Ripper.lex(src).map {|token| token.drop(1) } # 位置情報は捨てる
.map {|sym,val| [conv.(sym), val] } # 興味あるトークン以外は ANY に変換する
.reverse # pop で取れるように反転
#pp @q
do_parse
end
private
def next_token
@q.pop
end
def color(val, code) # 色付けは、ANSIエスケープシーケンスで画面制御
"\e[#{code}m#{val.join}\e[m"
end
---- footer
if __FILE__ == $0
puts HighlightParser.new.parse ARGF.read
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment