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

整数の四則演算計算機 arith.rb

修正版の peg.rb を利用して、整数の四則演算計算機 arith.rb を作った。

文法定義の部分のコメントは、それに相当する PEG の記法だ。これを見ても分かるように、PEG では再帰的定義を多用しなくても文法を記述することができる。PEG で文法を記述するときのコツのようなものがあらわれていると思ったので紹介する。

ソースリストの順番をみれば分かるように、完全にトップダウンで記述していくことができる。PEG に慣れてきたら、パーサなんて朝飯前と言いはじめるかもしれない。

ファイル名: arith.rb

require 'peg.rb'

parser = Peg.new


# program <- spacing expr

parser.mkseq('program', 'spacing and expr', 'puts pop')


# expr <- term ('+' term / '-' term)* / term

parser.mkslash('expr', 'term and add_sub_term_star', 'term')
parser.mkstar('add_sub_term_star', 'add_sub_term')
parser.mkslash('add_sub_term', 'add_term', 'sub_term')
parser.mkseq('add_term', 'add and term', 'push(pop + pop)')
parser.mkseq('sub_term', 'sub and term', 'a = pop; b = pop; push(b - a)')


# term <- factor ('*' factor / '/' factor)* / factor

parser.mkslash('term', 'factor and mul_div_factor_star', 'factor')
parser.mkstar('mul_div_factor_star', 'mul_div_factor')
parser.mkslash('mul_div_factor', 'mul_factor', 'div_factor')
parser.mkseq('mul_factor', 'mul and factor', 'push(pop * pop)')
parser.mkseq('div_factor', 'div and factor', 'a = pop; b = pop; push(b / a)')


# factor <- number / '(' expr ')'

parser.mkslash('factor','number', 'open and expr and close')


# scanner

parser.mkterm('spacing', '/\A\s*/')
parser.mkterm('number', '/\A[-]?[1-9][0-9]*\s*/', 'push(@match.to_i)')
parser.mkterm('add', '/\A\+\s*/')
parser.mkterm('sub', '/\A-\s*/')
parser.mkterm('mul', '/\A\*\s*/')
parser.mkterm('div', '/\A\/\s*/')
parser.mkterm('open', '/\A\(\s*/')
parser.mkterm('close', '/\A\)\s*/')


# main loop

while true
  print 'arithmatic> '
  parser.line = gets
  exit if (parser.line =~ /exit/)
  parser.program
end
by tnomura9 | 2008-05-04 01:36 | Ruby | Comments(0)
<< PEG コンパイラ・コンパイラ... peg.rb バク修正 >>