
= REX: Ruby Lex for Racc


== 概要

  Racc と併用する Ruby 用の字句スキャナ生成ツール。


== 使い方

  rex [options] grammarfile

  -o  --output-file  filename   出力ファイル名指定
  -s  --stub                    デバッグ用の主処理を付加
  -i  --ignorecase              大文字小文字を区別しない
  -C  --check-only              文法検査のみ
      --independent             非依存モード
  -d  --debug                   デバッグ情報表示
  -h  --help                    使い方の説明
      --version                 バージョン表明
      --copyright               著作権情報表示


== デフォルトの出力ファイル名

  foo.rex  について  foo.rex.rb  を出力する。
  以下のように利用されることを想定している。

    require 'foo.rex' 


== 入力ファイル構造

  頭部、規則部、脚部の順に定義する。
  規則部には、複数の節が含まれる。
  各節は、行頭がキーワードで始まる。

  概要：

    [頭部]
    "class" Foo
    ["option"
      [オプション] ]
    ["inner"
      [メソッド定義] ]
    ["macro"
      [マクロ名  正規表現] ]
    "rule"
      [スタート状態]  パターン  [アクション]
    "end"
    [脚部]


=== 入力ファイル記述例

    class Foo
    macro
      BLANK         \s+
      DIGIT         \d+
    rule
      {BLANK}
      {DIGIT}       { [:NUMBER, text.to_i] }
      .             { [text, text] }
    end


== 頭部（省略可能）

  規則部の定義以前に記述された内容は、すべて出力ファイル冒頭に転記される。


== 脚部（省略可能）

  規則部の定義以降に記述された内容は、すべて出力ファイル末尾に転記される。


== 規則部

  規則部は "class" キーワードから始まる行から "end" キーワードから始まる
  行までである。
  "class" キーワードに続けて出力するクラス名を指定する。
  モジュール名で修飾すると、モジュール内クラスとなる。
  Racc::Parser を継承したクラスを生成する。


=== 規則部定義例

    class Foo
    class Bar::Foo


== オプション（省略可能）

  この節は "option" キーワードで始まる。

    "ignorecase"  大文字小文字を区別しない。
    "stub"        デバッグ用の主処理を付加
    "independent" 非依存モード。Racc を継承しない。

== 内部ユーザコード（省略可能）

  この節は "inner" キーワードで始まる。
  ここで定義した内容は、生成したスキャナのクラスの内部で定義される。


== マクロ定義（省略可能）

  この節は "macro" キーワードで始まる。
  一綴りの正規表現に名前をつける。
  \ でエスケープすることで空白を含めることができる。

=== マクロ定義例

    DIGIT         \d+
    IDENT         [a-zA-Z_][a-zA-Z0-9_]*
    BLANK         [\ \t]+
    REMIN         \/\*
    REMOUT        \*\/


== 走査規則

  この節は "rule" キーワードで始まる。

  [state]  pattern  [actions]


=== state: スタート状態（省略可能）

    スタート状態は ":" を前置する識別子で表される。
    続く英字が大文字のとき、排他的スタート状態となる。
    小文字のとき、包含的スタート状態となる。
    スタート状態の初期値および省略時値は nil である。


=== pattern: 文字列パターン

    文字列を特定するための正規表現。
    正規表現の記述には、括弧で括ったマクロ定義を用いることができる。
    空白を含む正規表現を用いるには、マクロを使用する。


=== actions: アクション（省略可能）

    パターンに適合するときアクションは実行される。
    適切なトークンを作成する処理を定義する。
    トークンは、種別と値の二項を持つ配列、または nil である。
    トークンを作成するために以下の要素を利用できる。

      lineno  入力行番号     ( Read Only )
      text    検出した文字列 ( Read Only )
      state   スタート状態   ( Read/Write )

    アクションは { } で括った Ruby のブロックである。
    ブロックを越えて制御の流れを変える機能を使用してはいけない。
    ( return, exit, next, break, ... )
    アクションが省略されると、適合した文字列は破棄されて次の走査に進む。


=== 走査規則定義例

        {REMIN}                 { self.state = :REM ; [:REM_IN, text] }
  :REM  {REMOUT}                { self.state = nil ; [:REM_OUT, text] }
  :REM  (.+)(?={REMOUT})        { [:COMMENT, text] }
        {BLANK}
        -?{DIGIT}               { [:NUMBER, text.to_i] }
        {WORD}                  { [:word, text] }
        .                       { [text, text] }


== コメント（省略可能）

  各行において "#" から 行末までがコメントになる。


== 生成したクラスの使い方

=== scan_setup()

    スキャナの実行開始時に初期化するためのイベント。
    再定義して使用する。

=== scan_str( str )

    定義された文法によって記述された文字列を解釈する。
    token を内部に保持する。


=== scan_file( filename )

    定義された文法によって記述されたファイルを読み込む。
    token を内部に保持する。


=== next_token

    内部に保持する token をひとつずつ取り出す。
    最後は nil を返す。


== 注意

  本仕様は暫定的であり、予告なく変更される場合がある。

