image

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

検索

最近のトラックバック

無料ブログはココログ

« ピックアップ:XML Pipeline Language, BitTorrentなアーケードゲーム, etc... | トップページ | ピックアップ:社内ブログ/社内SNS失敗学, Ruby で debug する7つの方法, etc ... »

2007-06-02

racc で xvcd を生成することを試し始めた (その2)

前回の投稿では、xfy の xvcd には書式が似ていても正しくない出力だった。

前回の出力内容例
---------------

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

今回は、xvcd の一部分としてはそれなりに正しい出力が得られようにした。
今回の出力内容例
---------------

<instruction:variable name="message" select="'test ok'"/>
<instruction:message-box>
  <xvcd:value-of select="'abc'"/>
  <xvcd:value-of select="'xyz'"/>
</instruction:message-box>
<instruction:message-box>
  <xvcd:value-of select="$message"/>
</instruction:message-box>

これを生成する入力ソースはこれ。

message = "test ok"
puts( "abc", "xyz" )

puts( message )

今回は、
        - ソース中の空行を無視するようにする
        - select="..." の中を'文字列' とか $変数名 と出力する
ようにした。

racc ソースはこれ。(変更部は #-- katoy で印をつけた)

class IntpParser
rule

  program :
          | program stmt EOL
          | program EOL          #-- katoy

  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
             {
               result = "'" + val[0] + "'"
             }
          | STRING
             {
               result = "'" + val[0] + "'"
             }

end

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

  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 )
    #-- katoy
    if func == :puts
       @builder.tag!("instruction:message-box") {
         args.each do |k|
           @builder.tag!("xvcd:value-of", "select"=> k)
         end
       }
    end
  end

  def do_assign( vname, val )
    #-- katoy
    @vtable[ vname ] = '$' + vname.to_s
    @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

次は、if else の条件文、関数定義 を追加しよう。

xfy/xvcd での <xvcd:choose> <xvcd:when>...</xvcd:otherwise> は書くのも読むのもちょっとシンドイ。これを少しでも簡易できればと思う。

for ループや while ループは、まずどのような xvcd を生成すべきかを検討する必要があるので、すぐには出来そうにないけど、if  else は比較的簡単にできるだろうと予想している。

« ピックアップ:XML Pipeline Language, BitTorrentなアーケードゲーム, etc... | トップページ | ピックアップ:社内ブログ/社内SNS失敗学, Ruby で debug する7つの方法, etc ... »

コメント

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

トラックバック


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

« ピックアップ:XML Pipeline Language, BitTorrentなアーケードゲーム, etc... | トップページ | ピックアップ:社内ブログ/社内SNS失敗学, Ruby で debug する7つの方法, 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 あわせて読みたい

リンク