ここ三日くらいの寝不足により、こんなのが動くようになった。
require 'racc' grammar = Racc::Grammar.define { g = self g.precedence_table { prechigh left '*', '/' left '+', '-' preclow } g.target = rule(:exp) | rule() { 0 } g.exp = rule(:exp, '+', :exp) {|x,_,y| x + y }\ | rule(:exp, '-', :exp) {|x,_,y| x - y }\ | rule(:exp, '*', :exp) {|x,_,y| x * y }\ | rule(:exp, '/', :exp) {|x,_,y| x / y }\ | rule('(', :exp, ')') {|_,n,_| n }\ | rule('-', :NUMBER) {|_,n| -n }\ | rule(:NUMBER) } Calculator = grammar.parser_class
この仕組み自体より、腐ったコードを書き直すほうに時間を取られてしまった。
(01:21)
どうせなら「n 回以上の繰り返し」とか「省略可能」とかも実装したいところだが、 インターフェイスをどーしたもんかなー。 現状の rule(:exp, '+', :exp) {....} てのもベストとは言い難いし。
(01:27)
まさかとは思ったが、VALUE 作ってるのに全然マークしてないじゃん!! よくこれまで落ちなかったなー、これ……。 1.8.5 の前に見付かってよかったと考えるべきか、 それともすでに手遅れと考えるべきだろうか。
(22:18)
http://www.vim.org/scripts/script.php?script_id=1589
vim で SKK が使えるプラグイン。 こんなものがあったのか! すっげえ便利だー! 即座に常用決定。
(01:55)
http://www.unixuser.jp/magazine/2006/200608.html
オープンソースマガジン 8 月号で記事を書かせてもらいました。 ハッカー養成塾という連載のうち一本で、 「オープンソースマガジンの中心 (付近のページ) でバカと叫ぶ」です。 いやー、もうね、なんかね、何書いてもいいと言われたので、 久しぶりにリミッターを外して書いてみました。 よかったら読んでやってください。
(06:09)
http://jp.rubyist.net/magazine/?0015
Rubyist Magazine 15 号でた。
なかなか掲載できなかった Tropy の添削記事をようやく出せた。 今月も長い。最初はもっと長かった。
今月号は添削と YARV 以外読んでないので、おれもこれから読む。
(00:25)
http://akiba.ascii24.com/akiba/column/latestparts/2006/07/14/663447-002.html
なにいいい! Core 2 Duo は 64 ビットモードのが遅いって、なんだそれは! いくら絶対速度で Opteron に負けてないっても、 クロックとプロセスルールの差だけで勝ってるんじゃねえのこれ? おれの使いかたじゃ SSE なんて使わねえし。 Opteron のクロックが上がったらまたすぐ負けたりしてな。萎えるー。
急激に Core 2 買う気が失せてきた。 やっぱりもうしばらくは AMD にしよう……。
(00:28)
■
タナカコウイチロウ [田中という者です。
先日のHaskell読書会に出ていた者です。
参照透過性についての話題。
ライカン著「言語哲学」(けい草書房)で、クワインの用語法で
”指示的に透明(transparent)”(p.20)がありました。
また、飯田隆著「言語哲学大全III」(けい草書房)の索引には、
”指示的に透明な(referentially transparent)文脈”の項目が
ありました。(自分は理解していません)
しかし、クワインの用語と因果関係はアルのかと、自問したくなります。
それでは。]
■
青木 [あ、これはどうも。クワインかー。ちょっとぐぐってみたところ、
http://sources.redhat.com/ml/guile/1998-08/msg00401.html
というページがありました。このページによると、クワインは
"Principia Mathematica" から持ってきたとか、もしかしたら
フレーゲかもー、とか書いてありますね。プログラミング言語に
持ち込まれたときに意味が変化してるようです。]
StringScanner.new("").scan(//) が nil になるよ問題。 これはだいたい問題なく終わる。
Ruby 1.8 でテストが失敗するよーと思っていたら、 鬼車と GNU regex の挙動の差が原因だった。 明示的なチェックを入れて修正完了。
(19:06)
ファイルシステムをまたぐ mv が元のファイルを消してなかった件。当然バグ。 なんか見たことあると思ってたら、妙に迂遠な経路を経て [ruby-dev:28223] で報告されていたやつだった。修正済。
mv をアトミックにしろと言われてもなあ。 てんぷファイル (添付じゃなくて tmp な) を作るのは好きじゃないんだよね俺。
(19:10)
これは 2ch に流れてたやつと同じかなあ。
require 'net/http' Net::HTTP.start('www3.nikkei.co.jp') {|h| res = h.post('/nkave/data/index.cfm', 'yyyy=1950&mm=1&dd=11') puts res.body }
このコードでなぜか Content-Type が付かなくなるらしい。 なぜか確認されてるのは mswin32 だけ。 ヘッダの操作なんて文字列処理しかしてねーのに どうしてプラットフォーム依存になるのか、激しく謎だ。
VC++8 / Windows XP SP2 で何事もなく動いてしまった。
ああそうか、これは CVS HEAD だった。 1.8 じゃないとだめなんだなたぶん。 Ruby 1.8 で試すとあっさり再現した。
あ、わかった。req.content_type が nil にならないからだ。 HEAD は修正したけど 1.8 は直してなかったのか。 なんかこのへんは他にもバグバグしてるなあ。
ん? なんだ、じゃあ別に mswin32 限定でもなんでもないんじゃないか。 1.8.3 〜 1.8.4 ならどのプラットフォームでも同じように失敗する。
ちなみにデフォルトで Content-Type をセットするのは、 Content-Type がついてないと Tomcat が文句を言う、 と文句を言う人が多かったから。だったような気がする。
(22:01)
net/http の deflate 対応パッチをもらった。 おおむねそのまま使えそうなので、 近いうちに修正を加えて 1.9 に取り込む予定。
(15:45)
レポートを書いてたはずなのにいつのまにか Racc をいじっている不思議。 今日は Parsec ちっくに many とか option を使えるようにしてみた。
どことなく C 風の文法 (アクションはまだ適当)
grammar = Racc::Grammar.define { g = self precedence_table { higher right '[' right '*@', '&@', :CAST right '+@', '-@', '!' left '*', '/' left '+', '-' left ">>", "<<" left '&' left '|' left "==", "!=", '>', '>=', '<', '<=' left "&&" left "||" lower } g.program = many(:decl) g.decl = seq(:defvar) {|field| declare field }\ | seq(:defun) {|func| declare func }\ | seq(:defstruct) {|struct| define_type struct }\ | seq(:defunion) {|union| define_type union } g.defvar = seq(:storage, :type, :IDENT, option(:initval), ';') { |storage, type, name, val, _| Field.new(storage, type, name, val) } g.initval = seq('=', :expr) {|_, expr| expr } g.defun = seq( :storage, :type, :IDENT, '(', :params, ')', '{', :scope, '}') { |storage, type, name, _, params, _, _, body, _| Function.new(storage, type, name, params, body) } g.params = separated_by(',', :slot) g.defstruct = seq(:STRUCT, :IDENT, '{', many(:memb), '}', ';') { |_, tag, _, membs, _, _| StructType.new(tag, membs) } g.defunion = seq(:UNION, :IDENT, '{', many(:memb), '}', ';') { |_, tag, _, membs, _, _| UnionType.new(tag, membs) } g.memb = seq(:slot, ';') {|slot, _| slot } g.struct_decl = seq(:STRUCT, :IDENT, ';') {|_, tag, _| StructType.new(tag, nil) } g.union_decl = seq(:UNION, :IDENT, ';') {|_, tag, _| UnionType.new(tag, nil) } g.scope = seq(_ { push_scope }, many(:vardecl), :stmts) {|_, decls, stmts| pop_scope ScopeNode.new(decls, stmts) } g.storage = null() | seq(:STATIC) | seq(:EXTERN) g.slot = seq(:type, :IDENT) {|type, name| Slot.new(type, new) } g.type = seq(:VOID) {|_| @types.void }\ | seq(:CHAR) {|_| @types.char }\ | seq(:SHORT) {|_| @types.short }\ | seq(:INT) {|_| @types.int }\ | seq(:LONG) {|_| @types.long }\ | seq(:LONG, :LONG) {|_,_| @types.longlong }\ | seq(:type, '[',']') {|t,_,_| @types.array_of(t) }\ | seq(:type, '*') {|t,_,_| @types.pointer_to(t) }\ | seq(:STRUCT, :IDENT) {|_, tag| @types.struct(tag) }\ | seq(:UNION, :IDENT) {|_, tag| @types.union(tag) } g.stmts = many(:stmt) {|stmts| stmts.compact } g.stmt = seq(';') { nil }\ | seq(:expr, ';') {|node, _| node }\ | seq(:IF, '(', :expr, ')', '{', :scope, '}', option(:else)){ |_, _, cond, _, _, then_body, _, else_node| n = IfNode.new(cond, then_body, else_node) n.location = cond.location n }\ | seq(:WHILE, '(', :expr, ')', '{', :scope, '}') { |_, _, cond, _, _, body, _| n = WhileNode.new(cond, body) n.location = cond.location n }\ | seq(:BREAK, ';') {|*| BreakNode.new(nil) }\ | seq(:CONTINUE, ';') {|*| ContinueNode.new(nil) }\ | seq(:RETURN, ';') {|*| ReturnNode.new(nil) }\ | seq(:RETURN, :expr, ';') {|_, expr, _| ReturnNode.new(expr) } g.else = seq(:ELSE, '{', :stmts, '}') {|_, _, body, _| body } g.expr = seq(:primary)\ | seq(:expr, '+', :expr) {|*a| newnode(BinaryOpNode, *a) }\ | seq(:expr, '-', :expr) {|*a| newnode(BinaryOpNode, *a) }\ | seq(:expr, '*', :expr) {|*a| newnode(BinaryOpNode, *a) }\ | seq(:expr, '/', :expr) {|*a| newnode(BinaryOpNode, *a) }\ | seq(:expr, '&', :expr) {|*a| newnode(BinaryOpNode, *a) }\ | seq(:expr, '|', :expr) {|*a| newnode(BinaryOpNode, *a) }\ | seq(:expr, '>>', :expr) {|*a| newnode(BinaryOpNode, *a) }\ | seq(:expr, '<<', :expr) {|*a| newnode(BinaryOpNode, *a) }\ | seq(:expr, '>', :expr) {|*a| newnode(BinaryOpNode, *a) }\ | seq(:expr, '>=', :expr) {|*a| newnode(BinaryOpNode, *a) }\ | seq(:expr, '<', :expr) {|*a| newnode(BinaryOpNode, *a) }\ | seq(:expr, '<=', :expr) {|*a| newnode(BinaryOpNode, *a) }\ | seq(:expr, '==', :expr) {|*a| newnode(BinaryOpNode, *a) }\ | seq(:expr, '!=', :expr) {|*a| newnode(BinaryOpNode, *a) }\ | seq(:expr, '&&', :expr) {|*a| newnode(BinaryOpNode, *a) }\ | seq(:expr, '||', :expr) {|*a| newnode(BinaryOpNode, *a) } g.primary = seq(:DIGIT) {|num| newnode(LiteralNode, @types.int, num) }\ | seq(:CHARACTER) {|ch| newnode(LiteralNode, @types.char, ch) }\ | seq(:STRING) {|str| newnode(LiteralNode, @target.types(@types.char), string_constant(str)) }\ | seq(:IDENT) {|sym| newnode(VarrefNode, @namespace, sym) }\ | seq('+', :primary).prec('+@') {|op, expr| newnode(UnaryOpNode, op, expr) }\ | seq('-', :primary).prec('-@') {|op, expr| newnode(UnaryOpNode, op, expr) }\ | seq('!', :primary) {|op, expr| newnode(UnaryOpNode, op, expr) }\ | seq('*', :primary).prec('*@') {|op, expr| newnode(UnaryOpNode, op, expr) }\ | seq('&', :primary).prec('&@') {|op, expr| newnode(UnaryOpNode, op, expr) }\ | seq(:primary, '[', :expr, ']') {|expr, _, idx, _| newnode(BinaryOpNode, '[]', expr, idx) }\ | seq(:IDENT, '(', separated_by(',', :expr), ')') { |name, _, args, _| newnode(FuncallNode, name, args) }\ | seq(:cast, :primary).prec(:CAST) {|type, node| CastNode.new(type, node) }\ | seq('(', :expr, ')') {|_, node, _| node } }
生成される文法
rule 1 program: rule 2 program: program decl rule 3 decl: defvar rule 4 decl: defun rule 5 decl: defstruct rule 6 decl: defunion rule 7 decl: struct_decl rule 8 decl: union_decl rule 9 defvar: storage type IDENT option@initval ";" rule 10 option@initval: rule 11 option@initval: initval rule 12 initval: "=" expr rule 13 defun: storage type IDENT "(" params ")" "{" scope "}" rule 14 separated_by1@slot: slot rule 15 separated_by1@slot: separated_by1@slot "," slot rule 16 params: rule 17 params: separated_by1@slot rule 18 defstruct: STRUCT IDENT "{" many@memb "}" ";" rule 19 many@memb: rule 20 many@memb: many@memb memb rule 21 defunion: UNION IDENT "{" many@memb "}" ";" rule 22 memb: slot ";" rule 23 struct_decl: STRUCT IDENT ";" rule 24 union_decl: UNION IDENT ";" rule 25 scope: @1 many@vardecl stmts rule 26 @1: rule 27 many@vardecl: rule 28 many@vardecl: many@vardecl vardecl rule 29 storage: rule 30 storage: STATIC rule 31 storage: EXTERN rule 32 slot: type IDENT rule 33 type: VOID rule 34 type: CHAR rule 35 type: SHORT rule 36 type: INT rule 37 type: LONG rule 38 type: LONG LONG rule 39 type: type "[" "]" rule 40 type: type "*" rule 41 type: STRUCT IDENT rule 42 type: UNION IDENT rule 43 stmts: many@stmt-1-base rule 44 many@stmt-1-base: rule 45 many@stmt-1-base: many@stmt-1-base stmt rule 46 stmt: ";" rule 47 stmt: expr ";" rule 48 stmt: IF "(" expr ")" "{" scope "}" option@else rule 49 stmt: WHILE "(" expr ")" "{" scope "}" rule 50 stmt: BREAK ";" rule 51 stmt: CONTINUE ";" rule 52 stmt: RETURN ";" rule 53 stmt: RETURN expr ";" rule 54 option@else: rule 55 option@else: else rule 56 else: ELSE "{" stmts "}" rule 57 expr: primary rule 58 expr: expr "+" expr rule 59 expr: expr "-" expr rule 60 expr: expr "*" expr rule 61 expr: expr "/" expr rule 62 expr: expr "&" expr rule 63 expr: expr "|" expr rule 64 expr: expr ">>" expr rule 65 expr: expr "<<" expr rule 66 expr: expr ">" expr rule 67 expr: expr ">=" expr rule 68 expr: expr "<" expr rule 69 expr: expr "<=" expr rule 70 expr: expr "==" expr rule 71 expr: expr "!=" expr rule 72 expr: expr "&&" expr rule 73 expr: expr "||" expr rule 74 primary: DIGIT rule 75 primary: CHARACTER rule 76 primary: STRING rule 77 primary: IDENT rule 78 primary: "+" primary rule 79 primary: "-" primary rule 80 primary: "!" primary rule 81 primary: "*" primary rule 82 primary: "&" primary rule 83 primary: primary "[" expr "]" rule 84 primary: IDENT "(" option@separated_by1@expr ")" rule 85 primary: cast primary rule 86 primary: "(" expr ")" rule 87 separated_by1@expr: expr rule 88 separated_by1@expr: separated_by1@expr "," expr rule 89 option@separated_by1@expr: rule 90 option@separated_by1@expr: separated_by1@expr
(03:10)
Copyright (c) 2002-2007 青木峰郎 / Minero Aoki. All rights reserved.
■ hyuki [読みました。思いっきりメタに話を振ってましたねー(^_^)]
■ 青木 [反応早っ。どうもありがとうございます。
ある人には「セカイ系ラノベぽい」と言われてちょっと納得しました。]