vim で *.c を編集すると妙なオートインデント (cindent) がかかる。 .vimrc で set nocindent としても切れないので気になってたんだが、 ようやく調べた。次のようにすれば切れるらしい。
au! filetypedetect * *.c au! filetypedetect * *.h
au! は autocmd! の略で autocmd (フックみたいなもの) を消す命令。 filetypedetect はフックの種類。 「*」はイベント (ファイルを開いたとか読んだとか) の種類。 「*.c」はフックするパターン。
どんなフックが登録されているか調べるには、 vim を起動してモードラインで「:au」と打つ。 これで登録されているフックが全部リストされる。 また、次のように「:au * *.c」と打つと「*.c」に限定して調べられる。
:au * *.c --- Auto-Commands --- filetypedetect BufNewFile *.c call <SID>FTlpc() filetypedetect BufRead *.c call <SID>FTlpc()
ファイル「*.c」に対するフックは
以上の調査結果から、cindent を止めるには、 「*.c」に対するフックを消せばいいとわかる。 最初は「:autocmd BufNewFile,BufRead *.c set nocindent」とやったら フックが上書きされるかなーと思ったんだが、 実際にやってみると、フックが追加されるだけで終わってしまった。 つまりフックは明示的に削除しなければいけない。 ここで vim のリファレンスを見て 「:autocmd! TYPE EVENT PATTERN」がフックを削除する命令だとわかった。 もう一回「:au * *.c」をよく見ると、 filetype.vim で使っている TYPE は filetypedetect だと出ている。 したがって、「*.c」に対するフックを削除する命令はこうだ。
au! filetypedetect * *.c
ここで、よくよく考えると、*.h に対してもやっぱりフックがかかっていることは想像に難くない。 そこで、覚えたばかりの :au コマンドで *.h も調べてみる。
:au * *.h --- Auto-Commands --- filetypedetect BufNewFile *.h if exists("c_syntax_for_h") | setf c | elseif exists("ch_syntax_fo r_h") | setf ch | else | setf cpp | endif filetypedetect BufRead *.h if exists("c_syntax_for_h") | setf c | elseif exists("ch_syntax_fo r_h") | setf ch | else | setf cpp | endif
やっぱりなんか登録されているので、これも消す。
au! filetypedetect * *.h
以上をまとめた結果は以下の通り。
au! filetypedetect * *.c au! filetypedetect * *.h
(20:45)
http://log.ttsky.net/article/17335736.html
http://log.ttsky.net/article/17364209.html
む、tdp4r が改良されている。 「|」で or が記述できたり、リストが「*0」とか「*1」で書けるのも便利そう。 しかし右辺の g. がちょっと邪魔かなあ。 左辺の「g.expr =」のときは別に構わないような気がするのだけど。
Racc でもどーにかしてみようかと思っていじりはじめたのだが、 前に書いた
Racc::Grammar.define { rule program, expr rule expr, '(', expr, ')' _ expr, '+', expr do .... end _ expr, '-', expr do .... end _ expr, '*', expr do .... end _ expr, '/', expr do .... end _ num }
てのだと大文字で始まる記号が書けないことにいま気付いた。甘かった。
いや待てよ、const_missing を使えばいけるかなあ。 const_missingっていつ実装されたんだっけ。1.8 にはあるのか。 じゃあ const_missing でやってみよう。
~/c/racc % ruby racc-onthefly.rb [:program, :expr] [:expr, :expr, "+", :expr, #<Proc:0x00002a95ebbbc8@/home/aamine/racc-onthefly.rb:53>] [:expr, :expr, "-", :expr, #<Proc:0x00002a95ebb808@/home/aamine/racc-onthefly.rb:54>] [:expr, :expr, "*", :expr, #<Proc:0x00002a95ebb470@/home/aamine/racc-onthefly.rb:55>] [:expr, :expr, "/", :expr, #<Proc:0x00002a95ebb0d8@/home/aamine/racc-onthefly.rb:56>] [:expr, :NUM]
できるじゃん。
あとは {...} での問題か。 do...end じゃなくて {...} を使うとルールの最後の記号を文字列にできない。 つまり、
rule expr, expr, '^' {|x| p x }
と書くと SyntaxError になってしまう。 これをどうにかするには……。
1. 括弧をつける。
rule(expr, expr, '^') {|x| p x }
いまひとつ。却下。
2. エスケープ (?)
rule expr, expr, terminal('^') {|x| p x }
なんかわかりにくい。
3. エスケープ (?) その 2
rule expr, expr, __('^') {|x| p x }
余計わかりにくいか。
4. エスケープ (?) その 3
rule expr, expr, char('^') {|x| p x }
うーん……。まあ、これのがマシ?
5. エスケープ (?) その 4
rule expr, expr, C('^') {|x| p x }
もうちょっとエスケープっぽくしてみた。
6. エスケープ (?) その 5
rule expr, expr, '^', __ {|x| p x }
……何にしても直感的でないことに違いはないのか?
7. Proc を明示的に生成してみる
rule expr, expr, '^', lambda {|x| p x }
うーん。
8. do...end を推奨してみる
rule expr, expr, '^' do |x| p x end
やっぱり 1 行で書くときは {...} がいいなあ。
tdp4r の代入スタイルもいいなあ。
Racc::Grammar.define {|g| g.program = rule(expr) g.expr = rule('(', expr, ')') g._ = rule(expr, '+', expr) {|x, _, y| x + y } g._ = rule(expr, '-', expr) {|x, _, y| x - y } g._ = rule(expr, '*', expr) {|x, _, y| x * y } g._ = rule(expr, '/', expr) {|x, _, y| x / y } g._ = rule(NUM) }
rule が邪魔だ。
Racc::Grammar.define {|g| g.program = expr g.expr = char('(').expr.char(')')
即値が使いづらいことこのうえないなこれは。やめよう。
g.expr = rule('(', expr, ')') \ | rule(expr, '+', expr) {|x, _, y| x + y }
書けないことはないが、バックスラッシュが邪魔くさい。
(23:14)
ああそうか、Windows のことなんて忘れてた。だるー。 コンパイルは ghc -cpp -DWIN32 だけで通るようになってるのだが、 ウェブサーバの設定がなあ。 つーか、こういうときは何を入れればいいんだろうね。 まさか読者全員が IIS 持ってるとも思えないし、 結局 Apache2 なのかな。
あー、ダルい。本当にダルい。 インストールと設定の説明書くのが一番嫌いだ。
ぐあー 80 番ポートが使われてるー。 まずったな、IIS が動いてるんだ。
えーと、Windows だと httpd.conf はどこにあるんだろう。 ……Program Files の下か。それでいいんだろうか。 UNIX で /usr/local/apache2/etc に置いてあるようなもの……なの……かなあ……。
DocumentRoot はどこだ。 これも Program Files の下か。いいのかなあーこれで。
ん? DocumentRoot じゃなくて UserDir を使ったほうがいいのかなあ。 Windows では……My Documents の下ね。 My Documents\My Website\ ……って、My が多すぎだろ。 めんどいから public_html に変えちまおう。
配置 C:\Documents and Settings\aamine\public_html\ll\index.cgi C:\Documents and Settings\aamine\public_html\ll\default.css C:\Documents and Settings\aamine\public_html\ll\config C:\Documents and Settings\aamine\public_html\ll\var\ C:\Documents and Settings\aamine\public_html\ll\template\
これでいいのかな。
(例によって) 動かない。UserDir の設定をロードしてなかった。
まだ動かない。サーバをリスタートしてなかった。
まだ動かない。.htaccess 書くの忘れてた。
動いた。しかし Edit が変だ。HTML が途中で切れてるな。 なんとなく binmode 関係のような気がする。
hSetBinaryMode stdin True hSetBinaryMode stdout True
を追加したらうまくいった。
嘘だった。セーブされてないじゃん。
ええ? 何だこれ。 データベースに書き込まれてないということは、 save に行ってすらいない?
わかった……。フォルダとファイルのパーミッションがないからだ。 なんてありがちな。手っ取り早く SYSTEM からフルコントロールにして解決。
……めんどくせー。
(02:17)
Copyright (c) 2002-2007 青木峰郎 / Minero Aoki. All rights reserved.
実は、右辺はgがなくてもOKです。右辺でgをわざわざ書いたのは"g.foo"でgを前置したシンボルだと見てはどうかと思ったためです。
なるほど。個人的には g. がないほうがより DSL ぽくて好きです。
ちなみに、tdp4r の 1.0.6 よりも新しい版ってどこかから入手できますか?
なんか RAA もエントリがなくなってるぽいし……。
define がないのであれば、所属を明確にする意味で g. が
付いてたほうがいいような感じはしますね。
でも define { ... } があるなら必要なさそう。
あっと、RubyForge にあったんですね。
いただきました。