Skip to content

Instantly share code, notes, and snippets.

@yayugu
Created July 24, 2011 04:29
Show Gist options
  • Save yayugu/1102245 to your computer and use it in GitHub Desktop.
Save yayugu/1102245 to your computer and use it in GitHub Desktop.
ybookMLのパーサ
class YbookMLParser
prechigh
left CHARACTER
nonassoc LOW
preclow
rule
target : text { p val[0] }
| /* none */ { "" }
text : text string { result = val[0] + val[1] }
| string
string : command
| word = LOW
command : '*' word arguments { result = "\\#{val[1]}#{val[2]}" }
| word argument { last_char = val[0][val[0].size - 1]
result = val[0][0..(val[0].size - 2)] + "\\ff#{last_char}#{val[1]}"}
arguments : arguments argument { result = val[0] + val[1] }
| argument
argument : '[' text ']' { result = "{#{val[1]}}" }
word : word CHARACTER { result = val[0] + val[1] }
| CHARACTER
end
---- header
require 'strscan'
require 'pp'
OPERATOR = %w(* [ ])
---- inner
def initialize
end
def parse(text)
@text = text
@s = StringScanner.new(text)
@scaned = []
while m = scan_operator || plain do
@scaned.push m # enqueue
end
pp @scaned
do_parse
end
def next_token
@scaned.shift # dequeue
end
def scan_operator
OPERATOR.each do |op|
if @s.scan(Regexp.new(Regexp.escape(op)))
return [@s[0], @s[0]]
end
end
nil
end
def plain
if @s.scan(/./m)
[:CHARACTER, @s[0]]
end
end
def on_error(t, val, vstack)
raise ParseError, "\nunexpected token #{val.inspect}"
end
---- footer
if $0 == __FILE__
parser = YbookMLParser.new
p parser.parse(STDIN.read)
end
=begin
#ふりがな
対象の文字:x
振るふりがな:y
とすると
x[y]
のように表記する
例.
 本[ほん]日[じつ]は晴[せい]天[てん]なり
複数文字のルビを振るときは
*furigana[x][y]
のように表記する
例.
*furigana[紫陽花][あじさい]が咲いている
#その他のコマンド
その他のコマンドも基本的に
*command[x][y][z]...
のように表記する
引数は1個以上でコマンドごとに可変
引数内にさらにコマンドを書くこともできる
*command[*command2[a]][y][z]...
=end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment