image

  • フォト Amazonギフト券
    ※この時計の時刻は、閲覧しているパソコンのものであり、必ずしも正確な時間とは限りません

検索

最近のトラックバック

無料ブログはココログ

« java クラスローダを利用する例を作成した | トップページ | ピックアップ: セカンドライフは使えるかもしれない, FLASH XMLイメージギャラリー, etc... »

2007-05-27

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.y

class IntpParser
rule

  program :
          | program stmt EOL

  stmt    : funcall
          | assign

  funcall : 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
          | STRING

end

---- inner
  require 'rubygems'
  require 'builder'

  def initialize
    @builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
    @vtable = {}
  end

  def 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 ]
    end

    do_parse
  end

  def next_token
    @q.shift
  end

  def do_funcall( func, args )
    if func == :puts
       @builder.tag!("instruction:message") {
         args.each do |k|
           @builder.tag!("xvcd:value-of", k)
         end
       }
    end
  end

  def do_assign( vname, val )
    @builder.tag!("instruction:variable", "name"=>"#{vname}", "select"=>"'#{val}'")
  end

  def 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... »

コメント

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: racc で xvcd を生成することを試し始めた:

« java クラスローダを利用する例を作成した | トップページ | ピックアップ: セカンドライフは使えるかもしれない, FLASH XMLイメージギャラリー, etc... »

mokuji

2013年12月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        

google

  • twitter
  • __
  • _
    Googleボットチェッカー

合わせて読む

  • 合わせて読む
    フィードメーター - katoy: cocolog あわせて読みたい

リンク