青木日記

<前の日 | この月 | 次の日>

2002-07-25

■ strscan

昼御飯たべてるあいだにアイデアを思いついたんですが 実装する余裕がなっしんぐなのでここにメモ。

現実的なスキャナを書くためのクラス。

lex = StringScanner::Lex.new
 
# 状態付きスキャナの場合、状態を定義する
# 最初に全部定義しとかないとローカル変数スコープの罠にはまる
# けどこのくらいは問題ないか。状態集合の定義にもなっててよいことだ。
st_word = lex.new_state
st_space = lex.new_state
 
# lex 自体に定義したアクションは全状態で通用する
# (ただし各状態のパターンのほうが優先)
lex.on_match(/\w+/) {|s|   # s = マッチした文字列
    lex.goto st_word       # 状態遷移
    break :IDENTIFIER, s   # 記号とその値
}
# 読み飛ばされる
lex.skip(/\s+/)
lex.skip(/\#.*/)
 
# stateに定義すると状態固有アクション
st_word.on_match(re1, re2) {|s|
    # 二つ以上の正規表現を渡すと or になる
    # (アクションの共有)
}
st_space.on_match(/\(/) {|s|
    ....
}
 
# クライアント (バイト列から記号列を得る)
lex.foreach_pair(str) do |sym, tok|
  ....
end

StringScanner に正規表現を複数連続で試すメソッドを C で定義すれば Lex クラスを Ruby で書いてもネイティブ Ruby コード並に早くなるんでは なかろうか。

■ column

ls みたく出力を縦横に並べたくて tabulate ってコマンドを 書いたんですが、column というコマンドがあるのですね。くそう。 でも Ruby ライブラリとしても使えるし、 一緒に書いた untabulate (tabulate の逆) はなかったからいいとしよう。

ちなみに columns というコマンドも発見したんですが、 シンボリックリンクでも張ってあるのかと思ったら こっちはゲームのコラムスでした。 どうやら cvsup を入れるときに入れた Module-3 にくっついてた模様。 補完効かなくなるもん入れるんじゃないよ。うざいので抹殺。

■ VS....?!

不覚でした。

まさかそんなものの賞味期限が切れるなんて思わないじゃないですか。

ソース、賞味期限 2002 年 1 月 21 日。

冷蔵庫をさらったら 7/1 賞味期限のヨーグルトも発見しましたよ。 なんなんだこの家は……

本日のツッコミ(全6件)
■ なかだ (2002-07-26 09:48)

うむむ、よく分かんなかったんすけど、こういうもの?

class Lex
  class State
    def initialize
      @rules = []
    end
    def on_match(pattern, action = proc)
      @rules << [pattern, action]
    end
    def match(src)
      pattern, action, m = nil
      @rules.each do |pattern, action|
        return action.call(m) if m = src.match(pattern)
      end
      nil
    end
  end

  def initialize
    @current = @default = new_state
    @stack = []
  end
  def goto(state)
    @current = state
  end
  def push(state)
    @stack.push(@current)
    goto state
  end
  def pop
    goto @stack.pop
  end
  def new_state
    State.new(self)
  end
  def on_match(pattern, action = proc)
    @default.on_match(pattern, action)
  end
  def foreach_pair(str)
    src = StringScanner.new(str)
    while t = @current.match(src)
      yield t
    end
  end
end

■ さく (2002-07-26 11:40)

一瞬、sauceじゃなくてsourceかと思ってしまいました。

■ ただただし (2002-07-26 12:29)

それを狙って書いたのではないかと思ったのだが

■ arton (2002-07-26 23:29)

そう言えば、賞味期限3ヶ月じゃなかったけな?(とっくに切れてる)

■ woods (2002-07-27 01:03)

まあ、賞味期限切れみたいなソースって銀行とかだとごろごろしてるみたいですけどね。

■ arton (2002-07-27 12:58)

銀行といえば、1999年12月31日が賞味期限ってのを大量に抱えてたとこですね。


<前の日 | この月 | 次の日>
2002|04|05|06|07|08|09|10|11|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|04|05|06|09|10|
2009|07|
2010|09|