bambooflow Note

ruby

最終更新:

Bot(ページ名リンク)

- view
メンバー限定 登録/ログイン

rubyでantlr3を使う





インストール


% gem install antlr3


はじめの一歩



文法ファイル(.g)作成から実行まで

次のファイルを準備する。

  • Hello.g
grammar Hello;
 
start_rule : 'hello' WS 'world' WS? EOF;
 
WS  : (' ' | '\n')+;
 

% antlr4ruby Hello.g
もしくは
% ruby -S antlr4ruby Hello.g

実行すると次のファイルが生成される。
HelloLexer.rb
HelloParser.rb
Hello.tokens

うまく生成できたら次に実行用のファイルを用意する。
  • hello.rb
require 'rubygems'
require 'HelloLexer'
require 'HelloParser'
 
str = "hello world"
lexer = Hello::Lexer.new str
parser = Hello::Parser.new lexer
parser.start_rule
 


実行
% ruby hello.rb

実行しても何も起きません。何も起きないとパース成功となる。


生成されたファイルをみる


  • HelloLexer.rb
module Hello
  …
  class Lexer < ANTLR3::Lexerdef initialize( input=nil, options = {} )
      super( input, options )
    enddef t__5!
      type = T__5
      channel = ANTLR3::DEFAULT_CHANNEL
 
      match( "hello" )
 
      @state.type = type
      @state.channel = channel
    ensure
    end
 
    def t__6!
 
      type = T__6
      channel = ANTLR3::DEFAULT_CHANNEL
 
      match( "world" )
 
      @state.type = type
      @state.channel = channel
    ensure
    end
 
    def ws!
      …
    ensure
    end
 
    def tokens!
      alt_2 = 3
      case look_2 = @input.peek( 1 )
      when 0x68 then alt_2 = 1
      when 0x77 then alt_2 = 2
      when 0xa, 0x20 then alt_2 = 3
      else
        raise NoViableAlternative( "", 2, 0 )
      end
      case alt_2
      when 1
        t__5!
      when 2
        t__6!
      when 3
        ws!
    endend
end
 

ANTLR3::Lexerを継承している
token!が呼ばれると、トークンごとに@stateへ適切な値がセットされる。
自動生成されたt__5が"hello", t__6が"world"に対応する。


  • HelloParser.rb
module Hello
  class Parser < ANTLR3::Parser
 
    def initialize( input, options = {} )
      super( input, options )
    end
 
    def start_rule
 
      begin
        match( T__5, TOKENS_FOLLOWING_T__5_IN_start_rule_12 )   # "hello"に相当
        match( WS, TOKENS_FOLLOWING_WS_IN_start_rule_14 )       # WSに相当
        match( T__6, TOKENS_FOLLOWING_T__6_IN_start_rule_16 )   # "world"に相当rescue ANTLR3::Error::RecognitionError => re
        report_error(re)
        recover(re)
      ensure
 
      end
    end
  end
end
 

ANTLR3::Parserが継承されている。
.gファイルで記述したstart_ruleがdef定義され、エントリーポイントとなっている。
match()を呼ぶたびにトークンを比較。
比較してトークンがマッチしないと、rescueからreport_error(re)が呼ばれエラー処理に入る。





参考ページ


タグ:

ANTLR ruby
記事メニュー
ウィキ募集バナー