人気ブログランキング | 話題のタグを見る

リアルタイム PEG

mkpeg_puts.rb のコードの puts の部分を eval に置き換えたのが mkpeg_eval.rb だ。これを require すると、プログラムの中で文法を定義しながらプログラムを書いていくことができる。これを使えば、次の例のように、正規表現では検出できない入れ子構造のパターンを検出することができる。

実行例

C:\Users\******\Documents\Ruby>irb
irb(main):001:0> require 'mkpeg_eval.rb'
=> true
irb(main):002:0> mk_terminal('a', '/^a/')
=> nil
irb(main):003:0> mk_terminal('open', '/\(/')
=> nil
irb(main):004:0> mk_terminal('close', '/\)/')
=> nil
irb(main):005:0> mk_slash('primary', 'a', 'open and expression and close')
=> nil
irb(main):006:0> mk_slash('expression', 'primary')
=> nil
irb(main):007:0> $line = '((((a))))'
=> "((((a))))"
irb(main):008:0> expression
=> true

ファイル名: mkpeg_eval.rb (リアルタイム PEG コンパイラ)

def mk_empty(func_name)
  prog = <<END
def #{func_name}
  return true
end
END
  eval prog
end

def mk_terminal(func_name, reg)
  prog = <<END
def #{func_name}
  if $line =~ #{reg}
    $line.sub!(#{reg}, '')
    return true
  else
    return false
  end
end
END
  eval prog
end

def mk_and_terminal(func_name, reg)
  prog = <<END
def #{func_name}
  if $line =~ #{reg}
    return true
  else
    return false
  end
end
END
eval prog
end

def mk_not_terminal(func_name, reg)
  prog = <<END
def #{func_name}
  if $line =~ #{reg}
    return false
  else
    return true
  end
end
END
eval prog
end

def mk_and(func_name, expr)
  prog = <<END
def #{func_name}
  line = $line.dup
  if ( #{expr} )
    $line = line
    return true
  else
    return false
  end
end
END
eval prog
end

def mk_not(func_name, expr)
  prog = <<END
def #{func_name}
  line = $line.dup
  if ( #{expr} )
    $line = line
    return false
  else
    return true
  end
end
END
eval prog
end

def mk_star(func_name, expr)
  prog = <<END
def #{func_name}
  while ( #{expr} )
  end
  return true
end
END
  eval prog
end

def mk_slash(func_name, *exprs)
  prog = <<END
def #{func_name}
  line = $line.dup
END
  for expr in exprs
    prog += <<END
  $line = line
  if ( #{expr} )
    return true
  end
END
  end
  prog += <<END
  $line = line
  return false
end
END
  eval prog
end
by tnomura9 | 2008-04-22 22:33 | Ruby | Comments(0)
<< PEG の秘密 PEG コンパイラ? >>