image

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

検索

最近のトラックバック

無料ブログはココログ

« 2007-05-26 | トップページ | 2007-05-28 »

2007-05-27

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 クラスローダを利用する例を作成した

java クラスローダを利用する例を以下に置いた。

- http://homepage2.nifty.com/youichi_kato/src.html
> > java のクラスロード (plugin 機構と、クラス再ロード)
    plugin-2007-05-27.tgz(2007-05-27)
    00README.txt(2007-05-27)

これは、blog 機能の投稿した内容の plugin 機構の例と、クラス定義ソースコードを編集すると自動で compile/再ロードする例 を組み合わせてみた物だ。

グラフを描くアプリで、
数式 Editor/解釈処理を作らず 直接 関数処理を java コードで定義させてしまうという利用法も考えられる。

ここでつかった dynacode (自動再ロード)の仕組みは、そのまま xfy でも利用できると思う。

« 2007-05-26 | トップページ | 2007-05-28 »

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 あわせて読みたい

リンク