|
About this page
カテゴリー Computerに属する記事の一覧ページです。
現在このカテゴリーには129本の記事があります。 カテゴリー Computerの説明: コンピュータに関することが書いてあります。 Latest 5 Entries
EBNFをRacc形式に変換前回の記事『VHDLの可視化ができないものかと』のコメント欄に少し書きましたが、VHDLを可視化できないものかと思案中です。とりあえずプログラミング系のスキル向上も兼ねて、VHDLのパーサくらいこさえてみようと一念発起してみました。パーサジェネレータとしてはRubyベースのRaccを使うことにします。 VHDLはその定義が、定義記法の1つであるBNFを拡張したEBNFによって行われています。例えばVHDL-93のEBNF定義は『Hyperlinked VHDL-93 BNF Syntax』にあります。この定義をパーサジェネレータにうまいこと食わせられれば、パーサ生成に向けた第一歩をクリアすることができるという寸法です。 しかしながらRaccはBNFに近い形式のみでEBNFをそのまま受け付けてくれるわけではありません。特に問題となるのが、EBNFのみで可能なブレース('[', ']')やブラケット('{', '}')を使った省略可能及び繰り返しの表記で、これをBNFでも表記可能な再帰定義で書き換えなければなりません。 書き換えの例をあげると以下のようになります。EBNF、それを変換したBNFの順に示します。 hoge_def ::= { ada_def [ basha_def ] }
hoge_def ::= hoge_def_loop
hoge_def_loop ::= ada_def basha_def hoge_def_loop | ada_def hoge_def_loop | VHDLクラスのまじめな言語になると、これを手動で変換というのはかなり大変です。そこでRubyでVHDLのEBNF用変換スクリプトebnf2raccy.rbを書いてみました。これで記法の問題、並びにキーワードの終端記号化を行っています。VHDLのEBNF定義ebnf.txtから、このスクリプトによって生成したRacc用入力ファイルをRaccで処理したところ、shift/reduce、reduce/reduce conflictsがいくつか出ていますが、EBNFからBNFへの記法変換についてはうまくいっているようです。 これらをもとにパーサをこさえようとしていますが、現在のところ入力文字列を意味単位(トークン)に区切ってくれるスキャナとの関係をどうしようかと思案中です。VHDLの定義自体は文字指向、つまり一文字ずつ処理するように作ってあるようですが、パーサとしては字句指向、つまりは単語単位でリテラルとしてスキャナからトークンが生成されたほうが都合がよいと思います。そこでVHDLの定義の中で、文字を結合して意味を形作っている下位部分をいくつか書き換えようと考えています。 ※(2008/6/24)正規表現を使ってリテラル単位でスキャナからトークンが生成されるように変更してみました。リンク先のファイルも更新してあります。 ※※(2008/6/25)キーワードと規則名が一部被っていたことに愕然としました。literal、range等です。BNF側を修正することで対応しました。また今後の方針ですが、VHDLの文法がなかなかお茶目のよう(定義済みの名前と定義がない名前で文法上の動作をかえる必要があるらしい、トークンの1つ先読みだけでは完全に文法が定まらない?)で、これをどうやってRaccが採用しているLALR(1)で実現するか難しいところです。おそらくアクションと組合わせて、next_tokenでスキャナからトークンを返す直前にちょっとした細工をかます必要があるのではないかと考えています。 秋月USBオーディオPCのサウンドカードが壊れてしまっていたので、秋月の新商品『USBオーディオモジュール』を組み立ててみました。ケースには同じく秋月の『ポリカーボネイトケース』を使っています。 なかなかいい音でなっています。アンプ部分がPCから遠いことが効いているのでしょうか。ケーブルや電源等あわせて原価2000円程度、工作に1時間程度かかりました。サウンドカードをジャンクで数百円で購入するよりも、いい仕事をしたという満足感が得られたので、よしとします。 RubyでアップローダCGIファイルをネット上でやり取りしなければならない事情がでてきまして、せっかくなので自習がてらCGIで動作するアップローダを作成してみました。前回web系のプログラミングをしたのは実に1年以上前のことなのでかなり感覚が鈍っていましたが、過去の遺産である『Trackback機能付き掲示板』を利用することで、何とか数時間でこさえることができました。せっかくなのでコードを公開したいと思います。RSSも吐いてくれます。 動作しているデモもあわせて公開します。なおデモなのでアップロードできるファイルのサイズ制限を10KBと厳しめ設定してあります。 作成にあたってはRubyを利用しましたが、標準添付ライブラリの CGI + PStore + ERB に助けられました。簡単なCGIを作るについては、これはかなり強力な組合せだと思います。 cvs2svnで文字コードが混在するcharsetを設定するサーバを移行した際に、ファイルのバージョン管理システムをCVSからより便利なSubversionに移行しました。僕の近辺ではバージョン管理システムを導入している方というのがほとんどいないのが現状ですが、もうこの便利さは嫌というほど思い知らされているので、日付ごとのディレクトリを切って管理をしている様子を見るといつも信じられない気持ちでいっぱいになります(笑)。というわけでこのシステムを使いやすく運用することにはかなり命をかけており、そんな状況での移行でした。 移行については、参考にしたサクラエディタの『cvs2svnによるリポジトリ変換』のようにcvs2svnを使い、なおかつ拡張子に基づいてファイルの種類(svn:mime-type)や文字コード(charset)をcvs2svnに教えてあげるauto-propsという設定ファイルを記述すれば、大抵のことはうまくいきます。しかしながら、ソースの文字コードが混在している(例えばWeb系のスクリプトはUTF-8で、M$関係のソースはMS932(Shift-JISの友達)で等)複数のプロジェクトを管理していたため、auto-propsで拡張子に基づいた文字コードを設定してしまうと、例えばTracなどを使って管理している内容をそのままWebで公開する際に少々まずいことがおきるようです。そこで対策を考えてみました。 はしめはauto-propsの設定ファイルをうまく表現することで対応できないかとも考えてみたのですが、auto-propsが拡張子を基準として動作しているため、この方法では不可能と判断しました。仕方がないのでcvs2svnのソースを改変しようかとも考えたのですが、たまたま上述の参考リンクで行われているcvs2svn --dump-onlyというコマンドで吐き出されるダンプファイルの形式が理解しやすいことを発見したので、これをcvsadmin loadでリポジトリに格納する前に修正することにしました。 修正に用いたRubyスクリプトはcvs2svn_mod_charset.rbです(再利用の際、プロジェクト名は修正してください)。使い方はcat (cvs2svn --dump-onlyしたダンプファイル) | ruby cvs2svn_mod_charset.rb | cvs2admin load where/to/svnrootです。非常に安直なスクリプトですが、ダンプファイルの形式が(同じく安直な)HTTPプロトコルの形式に似ていることもあり、おそらく多くの場合はこれで対応可能だと思います。 fsck_hfs Invalid extent entryサーバが昨日より故障していました。アクセスして戴いた皆様におかれましてはご不便をおかけしました、この度ようやく復活できたようです。 サーバはPowerMac G3(350MHz) + MacOSXの10.2.8で構成してあるのですが、そろそろHDDが寿命のようです、という事情は以前の記事等で察していただけるかと思います。早く新しいMacMiniサーバへ乗り換えたいのですが、なかなかまとまった時間(次のGW4連休がチャンスと睨んでいます)をとることができずに、ずるずる使い続けていました。そしてコトが起こったのです。 コトの発端はバージョン管理を行うCVS(Current Version System)をeclipse上からssh経由(extssh)で使っている際に発生しました。ssh経由での接続には成功するものの、ファイルの同期を行おうとすると、create_adm_p /tmp/cvs-serv(pid)/(dir) : File too large というエラーが表示されます。ディスクには余裕があったので、File too largeの部分に引っかかりながらも、サーバ側のcvsの動作を疑いました。サーバ側のcvsコマンドはソースよりコンパイルしてあったので、状況を追うのは簡単でした。ソースからcreate_adm_pをヒントにエラーの発生箇所を検索します。 find . \( -name "*.c" -o -name "*.h" \) -exec grep -n create_adm_p {} \; -print | less
調べた結果cvsの中でシステムコールであるmkdir関数を使用して/tmpに一時ディレクトリを作成しようとした際にエラーが起きたようです。ということでcvs自体は問題がないようです。加えて手動で/tmpの下にディレクトリを切ることはできたので、この時点ではファイルシステムが何となく怪しいという程度にしか状況を解析できませんでした。 一度この状況で放置をしていたのですが、さらに困ったことがおきました。scpで単純なファイルをコピーしようとすると、やはりFIle too largeと言われるようになりました。更にサーバにローカルログインしてファイルを作成しても同じ現象が発生します。この時点で完全にディスクが怪しいという確信を得られたので、ブートディスクのチェック fsck_hfs -fd / をしてみると、Invalid extent entryなるエラーが発生していました。どうやらファイルシステムが破壊されつつあるようです。 Appleの技術情報『ディスクユーティリティおよび fsck を使用して、起動時の問題を解決する、あるいはディスクをメインテナンスする 』によると、このような場合はセーフブートによる回復やシングルユーザモードでの回復処理の実行によって状況が打開されるとあります。しかしながら今回発生したInvalid extent entryのエラーは修復されませんでした。検索によれば、純正のコマンド(fsck_hfs)やツール(Disk First Aid)等で回復できない類のエラーもあり、その場合には市販のソフトを導入して解決することが可能であるという情報も見受けられました。 しかしながら市販のソフトを導入したところで回復する見込みが100%でないことを考えると、ここで頑張る価値はあると考えました。まずは詳細なエラー情報を入手するため、fsck_hfsコマンドに改造を施しました。fsck_hfsをビルドするのに必要となるソースをdarwin(MacOSXと共通なopen sourceの部分)の開発者サイトから入手します。目的のコードは10.2.8/diskdev_cmds-208.11.2になります。 入手したソースに対して適宜手を加え、Invalid extent entryを発生させている部分を絞り込みました。 fsck_hfs.tproj/dfalib/CatalogCheck.cにあるCheckFile関数内でCheckFileExtents関数からの返却値がエラー(405行目付近)となっているようです。どうやらファイルシステム内のファイルを管理しているテーブルで異常で発生しており、その問題箇所と関連するファイルの名前はCheckFile関数のローカル変数filenameをprintfで吐き出すことで得られました。 ここまでわかったので、ファイルシステムのテーブルを直接修正しようかとも考えましたが、とりあえずおとなしく当該ファイルをrmコマンドで削除してみました。するとfsck_hfsで別のエラーが確認されるも、技術情報に従ってシングルユーザモードで起動、fsck -rfd / を行うと今度は全てのエラーが修復されました。これで無事解決に至りました。 この問題を振り返ってみると、サーバのHDDにバットセクタが発生している可能性が高いのではないかと考えられます。特にファイルシステムのテーブル部分は頻繁にアクセスがかかるので数年間の負荷に耐え切れずに今回のようなエラーが発生したのではないでしょうか。いずれにしても、できる限り早く新サーバに乗り換えたほうが先進衛生上好ましいようです。 Old Entries @ Computer
| |