racc で xvcd を生成することを試し始めた
racc の参考書として上の本を買ってきた。(racc とは ruby 版 yacc)
第1章の例に対して、ちょっと手をいれて、xml を吐くようにしてみた。
(まだまだ、全然ゴールには遠いが、xfy/xvcd 風の xml を出す第一歩としては十分でしょう。変数の扱い、コマンド定義、条件文 などをサポートしていこう...)
現状はこんな感じ。
-----------
$ cat src
message = "test ok"
puts( "abc", "xyz" )
-----------
$ ruby main.rb src
<instruction:variable name="message" select="'test ok'"/>
<instruction:message>
<xvcd:value-of>abc</xvcd:value-of>
<xvcd:value-of>xyz</xvcd:value-of>
</instruction:message>
ソースは以下。
---------
$ cat intp.yclass IntpParser
ruleprogram :
| program stmt EOLstmt : funcall
| assignfuncall : IDENT '(' args ')'
{
result = do_funcall( val[0], val[2] )
}
| IDENT '(' ')'
{
result = do_funcall( val[0], [] )
}args : primary
{
result = val
}
| args ',' primary
{
result.push val[2]
}assign : IDENT '=' primary
{
result = do_assign( val[0], val[2] )
}primary : IDENT
{
result = do_varref( result )
}
| NUMBER
| STRINGend
---- inner
require 'rubygems'
require 'builder'def initialize
@builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
@vtable = {}
enddef parse( f )
@q = []f.each do |line|
line.strip!
until line.empty? do
case line
when /¥A¥s+/, /¥A¥#.*/
;
when /¥A[a-zA-Z_]¥w*/
@q.push [ :IDENT, $&.intern ]
when /¥A¥d+/
@q.push [ :NUMBER, $&.to_i ]
when /¥A"(?:[^"¥¥]+|¥¥.)*"/
@q.push [ :STRING, eval($&) ]
when /¥A./
@q.push [ $&, $& ]
else
raise RuntimeError, 'must not happen'
end
line = $'
end
@q.push [ :EOL, nil ]
enddo_parse
enddef next_token
@q.shift
enddef do_funcall( func, args )
if func == :puts
@builder.tag!("instruction:message") {
args.each do |k|
@builder.tag!("xvcd:value-of", k)
end
}
end
enddef do_assign( vname, val )
@builder.tag!("instruction:variable", "name"=>"#{vname}", "select"=>"'#{val}'")
enddef do_varref( vname )
@vtable[ vname ] or raise NameError, "un-initialized variable #{vname}"
end---- footer
parser = IntpParser.new
if ARGV[0] then
File.open( ARGV[0] ) do |f|
parser.parse f
end
else
parser.parse $stdin
end
« java クラスローダを利用する例を作成した | トップページ | ピックアップ: セカンドライフは使えるかもしれない, FLASH XMLイメージギャラリー, etc... »
この記事へのコメントは終了しました。
« java クラスローダを利用する例を作成した | トップページ | ピックアップ: セカンドライフは使えるかもしれない, FLASH XMLイメージギャラリー, etc... »
コメント