# # poparser.ry - ruby version of msgfmt # # Copyright (C) 2002-2005 Masao Mutoh # # You may redistribute it and/or modify it under the same # license terms as Ruby. class GetText::PoParser token COMMENT MSGID MSGID_PLURAL MSGSTR STRING PLURAL_NUM rule msgfmt : /* empty */ | msgfmt comment | msgfmt message ; message : MSGID string_list MSGSTR string_list { if @fuzzy and $ignore_fuzzy if val[1] != "" $stderr.print _("Warning: fuzzy message was ignored.\n") $stderr.print " msgid '#{val[1]}'\n" else on_message('', unescape(val[3])) end @fuzzy = false else on_message(unescape(val[1]), unescape(val[3])) end result = "" } | MSGID string_list MSGID_PLURAL string_list msgstr_plural { if @fuzzy and $ignore_fuzzy if val[1] != "" $stderr.print _("Warning: fuzzy message was ignored.\n") $stderr.print "msgid = '#{val[1]}\n" else on_message('', unescape(val[3])) end @fuzzy = false else on_message(unescape(val[1]) + "\000" + unescape(val[3]), unescape(val[4])) end result = "" } ; msgstr_plural : msgstr_plural msgstr_plural_line { if val[0].size > 0 result = val[0] + "\000" + val[1] else result = "" end } | msgstr_plural_line ; msgstr_plural_line : MSGSTR PLURAL_NUM string_list { result = val[2] } ; comment : COMMENT { on_comment(val[0]) } #| COMMENT #; string_list : string_list STRING { result = val.delete_if{|item| item == ""}.join } | STRING { result = val[0] } ; end ---- inner include GetText GetText.bindtextdomain("rgettext") def unescape(orig) ret = orig.gsub(/\\n/, "\n") ret.gsub!(/\\t/, "\t") ret.gsub!(/\\r/, "\r") ret.gsub!(/\\"/, "\"") ret end def parse(str, data, ignore_fuzzy = true) @comments = [] @data = data @fuzzy = false $ignore_fuzzy = ignore_fuzzy str.strip! @q = [] until str.empty? do case str when /\A\s+/ str = $' when /\Amsgid_plural/ @q.push [:MSGID_PLURAL, $&] str = $' when /\Amsgid/ @q.push [:MSGID, $&] str = $' when /\Amsgstr/ @q.push [:MSGSTR, $&] str = $' when /\A\[(\d+)\]/ @q.push [:PLURAL_NUM, $1] str = $' when /\A\#~(.*)/ $stderr.print _("Warning: obsolete msgid exists.\n") $stderr.print " #{$&}\n" @q.push [:COMMENT, $&] str = $' when /\A\#(.*)/ @q.push [:COMMENT, $&] str = $' when /\A\"(.*)\"/ @q.push [:STRING, $1] str = $' else #c = str[0,1] #@q.push [:STRING, c] str = str[1..-1] end end @q.push [false, '$end'] if $DEBUG @q.each do |a,b| puts "[#{a}, #{b}]" end end @yydebug = true if $DEBUG do_parse if @comments.size > 0 @data.set_comment(:last, @comments.join("\n")) end @data end def next_token @q.shift end def on_message(msgid, msgstr) if msgstr.size > 0 @data[msgid] = msgstr @data.set_comment(msgid, @comments.join("\n")) end @comments.clear end def on_comment(comment) @fuzzy = true if (/fuzzy/ =~ comment) @comments << comment end ---- footer