- 締切済み
Pascalのtext型変数のresetについて
Pascalのソースプログラムで、text型の変数prdにreset(prd,'console :')という箇所があったのですが、これはどういった意味なんでしょうか?? Pascalはまったくの初心者なのですが、大学のゼミ課題でやる羽目になりました。 よろしくお願いいたします!
- みんなの回答 (10)
- 専門家の回答
みんなの回答
- sakusaker7
- ベストアンサー率62% (800/1280)
すみません。回答したつもりが、書いていませんでした。 >書き込み側と読み込み側のつじつまが合う >というのが申し訳ないのですがよくわかりません・・・ たとえば、書き出したときはdoubleのイメージなのに 読み込むときにそれを整数として読もうとしちゃうとか、 5桁で書いたのを7桁とか別の桁数として読もうとしちゃうとか そういうことです。 さすがにデバッグを逐一教えるわけにはいかないのですが、 まずは書き出したファイルのイメージが自分の意図したものと あっているかどうかを確認してみてください。 その際にはバイナリエディタとか、ダンプユーティリティが 役に立つでしょう。 あとは間違いない中間言語ファイルを自分で書いておいて、 解釈部にそれを食わせてただしく動作するか検査をするとか。 もう8月も終わりですねえ…
- sakusaker7
- ベストアンサー率62% (800/1280)
お礼/補足がついたときはメールがくるように 設定してますので、時間が多少あいても大丈夫ですよ。 まずpaslcals.exeですが、入力するPascalソースのファイルの最後の行が 改行で終わっていない場合、#8のお礼にあるような 動作をするようです。 コピペをするときに、最後の行の末尾に 改行をつけといてください。 > 中間言語のことなんですけど、僕の本のソースだと > このファイルを吐き出すときに、 write(a:5,' ',b:9);とかで桁数を指定してるんですよ。 > これはJavaに直すときにどうしたらいいんでしょうか? > このファイルを読み込むなら、文字列で空欄を作るとか、余計なことはしないほうがいいですよね? ぶっちゃけどうでもいいです。 書き込み側と読み込み側でつじつまが合っていれば 問題がないので、好きなように決めればよいです。 というのはかえって混乱させるかな? 昔のファイルにあるような固定桁のフォーマットであるなら、 桁数をそろえるための空白はないと困るでしょうが、 Javaでファイルの読み書きするならその辺は柔軟にできますから、 デバッグのときに読みやすいようにしておけば 良いと思います。 ファイル名はそれで問題ないでしょう。 ただし読み込む前には書き込みを終了して クローズしておくことをお忘れなく。
- sakusaker7
- ベストアンサー率62% (800/1280)
> エラーは出ないのですけど、プログラムリストだけでて終わりでした。 > これは普通は勝手に実行されるものですよね? リストが出てきた後、入力待ちになりませんでしたか? わたしのサンプルの場合だと、^Z(コントロールキーを押しながらZキー) を入力しないと、Pascalプログラムの 出力はでませんよ? > あと、long型を2進数で扱う方法ってあるんですか!? > 十進数にLをつけて大きな数字を扱うだけだと思ってました・・ 内部的には数値は二進数で処理されてますから、どうとでもできます。 import java.lang.*; public class BitwiseOpSample { public static void main(String[] args) { long v1 = (1L << 33); long v2 = (1L << 35); long v3 = v1 | v2 | (1L << 5); long v4 = v3 & (1L << 5); System.out.println("v1 = " + Long.toBinaryString(v1)); System.out.println("v2 = " + Long.toBinaryString(v2)); System.out.println("v3 = " + Long.toBinaryString(v3)); System.out.println("v4 = " + Long.toBinaryString(v4)); } } v1 = 1000000000000000000000000000000000 v2 = 100000000000000000000000000000000000 v3 = 101000000000000000000000000000100000 v4 = 100000 こんな感じ。 > この前のptinttablesメソッドは中間言語を書き出しているのですか? > これは記号表とATABとBTABを表のように見えるように書き出しているものであってますよね?? > これが中間言語なんでしょうか?? まあ中間言語といってもいろいろありますが、 今回のPascal-Sの場合はこの途中出力の内容を 中間言語と見なしていいと思います。 人間が見やすいような形でファイルに吐かれているとでも 考えればいいんじゃないでしょうか。 > 参照を書き出したファイル名にするようにしようと思うのですが、 すみません。ここが何をいわんとしているのか よく意味が取れませんでした。
お礼
質問してる身なのに遅くなってすみません。。 僕の場合、入力待ちにはなりませんでした。 例えば、こんなソースを喰わせてみたんですよ。 program hello(input, output); begin writeln(1+1); end. そしたら、 0 program hello(input, output); 0 begin 0 writeln(1+1); 5 end. とでて、すぐに C:\> が出てきてしまいます。 おかしいですよね!? 中間言語のことなんですけど、僕の本のソースだと このファイルを吐き出すときに、 write(a:5,' ',b:9);とかで桁数を指定してるんですよ。 これはJavaに直すときにどうしたらいいんでしょうか? このファイルを読み込むなら、文字列で空欄を作るとか、余計なことはしないほうがいいですよね? 参照を・・・の質問は、 インタプリタを実行するときに読み込むファイルの名前をを吐き出したファイル名にしようと思う という意味でした。 言葉足らずでもうしわけありませんでした。
- sakusaker7
- ベストアンサー率62% (800/1280)
どんなPascalプログラムを喰わせてみました? Pascalプログラム自体が何かアクションをするプログラムになってないと、 何も出力されないですよ? #プログラムリストは出ますが > このprdの参照先をJavaにするときは出力したファイル名に変えたりしたらダメなんですか? いや、問題ないですよ。 入力のために読み込む前に出力を終了してクローズしておけば大丈夫でしょう。 > あと、可変レコードをJavaで表現するのにはどうしたらいいんでしょうか・・・ > クラスにして、オブジェクトを作ろうかと思ったのですが、それじゃダメなんでしょうか? 基本的にはそれでいいと思いますよ。 可変レコードの型のそれぞれを一つのクラスにしておくと同時に、 それらの継承元となる抽象クラス(別に抽象でなくてもいいですけど)を 作っておいて、各クラスはその派生型ということにしておけば オブジェクトの並んだ配列を統一的に扱えるでしょう。 まあそのクラスをどう設計するかが一つポイントになると思いますが それはまたの機会に。 > あと、Javaに書き換える際に集合型は、配列を使おうかと思っているのですが、これも大丈夫ですかね?? 集合の要素はそんなに数が多くなかったと思うので、 long 型あたりを使っとけば64要素までに限定されますが 各種の集合演算が楽にできると思いますよ。 無論配列でもできるので、自分の実装しやすい方でよいでしょう。
お礼
遅くなってすみません、 結局ゼミの合宿には間に合わなかったのですが、期限が夏休み中に完成させろということになりました! 喰わせたソースは一応出力を使ってるので、画面に出力はされるはずなんですけど・・・ ちなみにsakusaker7さんが例として書いてくれたソースをコピペさせてもらって喰わせてみてもやはりエラーは出ないのですけど、プログラムリストだけでて終わりでした。 これは普通は勝手に実行されるものですよね? 参照を書き出したファイル名にするようにしようと思うのですが、 この前のptinttablesメソッドは中間言語を書き出しているのですか? これは記号表とATABとBTABを表のように見えるように書き出しているものであってますよね?? これが中間言語なんでしょうか?? あと、long型を2進数で扱う方法ってあるんですか!? 十進数にLをつけて大きな数字を扱うだけだと思ってました・・
- sakusaker7
- ベストアンサー率62% (800/1280)
いやいや、このソース自体は中間結果をファイルに書き出しているのは 間違いないと思います。ただ、その結果を取り込むのをどうやっているのかが これまでの情報ではわからないので、ゼミの課題としてこの処理系をJavaで 書き直すということになっているのなら、元のソースの記述によらず あなたが自分で決めてもいいんじゃないですか? ということです。 補足してもらったソースの断片から判断すると、psoutに Pascalソースを変換した中間言語を書き出しているので、 >write( 'Source listing file ? '); readin(outf); で取得しているリスティングファイルの名前を、読み込むために もう一回どこかでresetなどの引数として使っているとかしていても いいはずなんですが… interpret 手続きで読み出してくるのは prd で、これは 'console:' に reset していますし。 うーんわからん。 まあ一回ファイルに書き出してそれを読み直しているのは、時代的に メモリ領域がぜんぜん使えないという事情を反映しているものだと思うので、 素直にPascalソースの解釈結果をメモリ(配列)に溜めておいて、 procedure interpret ではそれを参照すれば良いと思います。 Pascalで使っているデータ構造をそのままJavaに書き写すことはできない (特に可変レコードとか)ので、JavaとPascalの知識の両方がそれなりに ないと移植も何もないと思うのですが、ゼミの先生もなにをお考えなのか… あ、 Pascal-s http://www.moorecad.com/standardpascal/pascals.html に、Windowsのコマンドプロンプトで動作する Pascal-Sの実行ファイルが ありますよ。この動作を参考にすればいいんじゃないですか? これのソースはないみたいですけど、このページの管理人に直訴すれば もらえるかもしれませんので Let's Try! 動作はこんな感じです >type hello.pas program hello(input, output); procedure proc; begin writeln('1+1=', 1+1) end; begin proc end. >pascals Pascal-S compiler/interpreter Input file `Srcfil': hello.pas ← ファイル名を入力 0 program hello(input, output); 0 procedure proc; 0 begin writeln('1+1=', 1+1) end; 7 begin 8 proc 8 end. ^Z ← プログラムに対する入力待ちらしいので、何もなしで ^Zを押下 input data missing (eof) 1+1= 2 11 steps
お礼
そうなんですかー。。 では、このprdの参照先をJavaにするときは出力したファイル名に変えたりしたらダメなんですか? あと、可変レコードをJavaで表現するのにはどうしたらいいんでしょうか・・・ クラスにして、オブジェクトを作ろうかと思ったのですが、それじゃダメなんでしょうか? あと、Javaに書き換える際に集合型は、配列を使おうかと思っているのですが、これも大丈夫ですかね?? 初歩的な質問ですみません。。
補足
コマンドプロンプトで動くコンパイラなのですが、 自分やってみたこところ、エラーはでないのですが、実行されないで終了という事態に陥ってしまいました。 なぜでしょう・・・
- sakusaker7
- ベストアンサー率62% (800/1280)
現物見ればすぐに解決できそうなんですが、手間かけてすみませんね。 急ぎなのに。 えと、とりあえずわかっていることをまとめます。 ・入力としてPascal-S のプログラムのファイルをとり ・これを中間言語コードに変換し ・手続き interpret で解釈実行 しています。 これはこれまで見たどのPascal-Sのソースでも共通なので、多分同じだと思います。 ただし、 Pascal-Sが書かれた年代が古くてUNIX的なやり方がとられていないので 手順的に少々不明な部分 があります。 たぶんUNIX上で組もうというプログラムなら、中間言語への変換部分と それの解釈実行を行う部分が独立したプログラムになっているはずです。 が、それはおいときまして、 27: begin { read } if eof(prd) then ps := redchk else case ir.y of 1: read(prd, s[s[t].i].i); 2: read(prd, s[s[t].i].r); 4: read(prd, s[s[t].i].c); end; この部分は、変換した中間言語を読み込んでいるところです。 prdが中間言語を読んでくる先のファイルで(多分標準入力に割り当てられてますが)、 それがファイルの終端になっていなければ読み込みを行います。 読込先はsという配列ですが、この定義は s: array (.1..stacksize.) of (*blockmark: *) record case types of (* s(.b+0.) = fct result *) ints: (i: integer); (* s(.b+1.) = return adr *) reals: (r: real); (* s(.b+2.) = static link *) bools: (b: boolean); (* s(.b+3.) = dynamic link*) chars: (c: char) (* s(.b+4.) = table index *) end; で、まあ一言で言うと、解釈系の状態をつんでおくスタックです。 あ、書き忘れてましたが > wirthさんのソースにすごく似た箇所があったんですけど、 1: read(prd, s[s[t].i].i); と 1: read(InputFile,s(.s(.t.).i.).i); たぶんこの辺の記述の事を指してのことだと思いますが、 これは読み込みもとのファイルが違いますが基本的には同じものです。 (. と .) というのは、それぞれ [ と ] の代替表現です。 Pascalはヨーロッパ生まれの言語ですので、'['のようなアメリカの コードに固有の記号が使えなかった場合がよくあったのです。 #大昔の話ですので、だいぶ前から事情は変わってます。 #興味があったら、C言語の「トライグラフ」について調べてみるといいですよ。 ということでこれまでの情報から考えると 標準入力から中間言語を読み込んできて処理する。というように なっている感じがするのですが、本の解説にでもプログラムの使い方とか 書いていませんか? > このprdはmainで定義されています、text型の変数は他にもpsin,psout,prrとあります。 > mainのbeginで、 > write( 'Source input file ? '); readln(inf); > reset(psin,inf); > > write( 'Source listing file ? '); readin(outf); > rewrite(psout,outf); > reset(prd, 'console :'); > rewrite(prr, 'console :'); 名前やメッセージから判断すると、 psin → Pascalソースのファイル psout → リスティングファイル(中間言語ファイルじゃない?) prr → ??? エラーメッセージの出力先か? とちとわからないところがありますねえ。 毎度手間を取らせますが、 http://www.246.dk/pascals1.html (Wirth先生版のソース)とほぼ同じであるなら、 procedure printtables; という手続きがあって、そこ中で writeやらwritelnやら呼び出していると思うんですが その辺どうなってますか? 出力先のファイル指定はなしでしょうか? と長々と書いてきましたが最終的な目的はJavaで書き直すということなんで、 Pascalソースを中間言語に落としたものをどうするか (ファイルに一回吐き出す or メモリに溜め込む)とか 中間言語への変換部分と解釈部分をまとめたひとつのプログラムにするか それぞれを独立したものにするか といった条件を考えた上で自分で(ひょっとしたらゼミ仲間の意見もあるかもしれませんが) 決めてしまってもいいのではないですか? ゼミの元締めも条件があるのならきちんと指示しているでしょうし。
お礼
とんでもないです、自分だけでやっていたらどんだけ時間かけてもできなさそうなので、感謝しています。 printtablesありました! procedure printtables; var i:integer; o:order; begin writeln(psout);writeln(psout);writeln(psout); writeln(psout,' identifiers link obj typ ref nrm lev adr'); writeln(psout); for i := btab[1].last to t do with tab[i] do writeln(psout,i,' ',name,link:5, ord(obj):5, ord(typ):5; ref:5, ord(normal):5, lev:5, adr:5); writeln(psout); writeln(psout);writeln(psout); writeln(psout,'blocks last lpar psze vsze'); writeln(psout); for i := 1 to b do with btab[i] do writeln(psout,i:4, last:9, lastpar:5, psize:5, vsize:5); writeln(psout);writeln(psout);writeln(psout); writeln(psout,'arrays xtyp etyp eref low high elsz size'); writeln(psout); for i := 1 to a do with atab[i] do writeln(psout,i:4, ord(inxtyp):9, ord(eltyp):5, elref:5, low:5, high:5, elsize:5, size:5); writeln(psout);writeln(psout);writeln(psout); writeln(psout,' code: ');writeln(psout); for i := 0 to lc-1 do begin write(psout);write(psout,i:5); o := code[i]; write(psout,o.f:5); if o.f < 31 then if o.f < 4 then write(psout,o.x:2, o.y:5) else write(psout,o.y:7) else write(psout,' '); writeln(psout,',') end; writeln(psout); writeln(psout,'Starting adress is ',tab[btab[1].last].adr:5) end { printtables } です。 リスティングファイルが中間言語なんですか!? この課題はゼミの中でも僕だけの課題なんです。 まだJavaをはじめて3ヶ月弱なんですよ。 それまで授業で簡単なプログラミング(それはc++ですが、クラス概念は省いてました)しかやったことがなかったので、 知識は皆無といっても過言じゃないくらいです。 教授は、とにかくJavaに翻訳して動くようにしろ。としか言われてなくて・・ なので、このソースがメモリに溜めて実行なのか、ファイルに吐き出すのかすら・・・すみません。。
補足
それぞれの手続きの意味は載ってたのですが、プログラムの使い方はのっていませんでした。。
- sakusaker7
- ベストアンサー率62% (800/1280)
すみません。本棚ひっくり返して探したんですが、箱詰めして物置送りに した中に入っているかもしれませんで、まだ見つかってません。 ただ、ネット検索したところ、件の本のものと違うような感じも しますが、Paslcal-S のものだというソースが何種類か見つかりました。 Pascal-S +246pascals+ http://www.246.dk/pascals.html ここからたどれます。 ざっと全部に目を通してみたのですが、reset(prd,'console :') というのはありませんでした。一引数のresetならあったんですが (Wirthその人のソースではresetは使われていませんでした)。 reset(file, 'title') という形式は確かに UCSD-Pascalが起源のようです。 http://miller.emu.id.au/pmiller/ucsd-psystem-um/reconstruct/02-01-02-io.html 2.1.2.1. Reset page121 PROCEDURE RESET(FILEID, TITLE: STRING); This procedure opens an already existing file for reading and writing and mark the file as open. とあるので、prdに 'console:' を割り当てるのはまあ間違いないでしょう。 read(prd) といったものが見当たらないということですけど、 このprdはどこでどのように定義されていますか? また、readに限らず使われているところがあれば抜き出してみてください。 あ、あと、readはどのように呼んでいたりしますか?
お礼
何度も何度もお手数おかけして申し訳ありません、本当にありがとうございます。 このprdはmainで定義されています、text型の変数は他にもpsin,psout,prrとあります。 mainのbeginで、 writeln('NOTE input/output for users program is console: '); writeln; write( 'Source input file ? '); readln(inf); reset(psin,inf); write( 'Source listing file ? '); readin(outf); rewrite(psout,outf); reset(prd, 'console :'); rewrite(prr, 'console :'); と書かれています。 出てくるところは、procedure interpret; のなかの、procedure inter0;という手続きで、 case ir.f of 0:begen.... .. .. 8:case ir.y of 0:s[t].i := abs(s..... .... ... ... 17: begin t := t+1; if t > stacksize then ps := stkchk else s[t].b := eof(prd) end; 18: begin t := t + 1; if t > stacksize then ps := stkchk else s[t].b := eoln(prd) end; end; がまずひとつです。 次に pricedure inter2; case ir.f of 20: begin... ... ... 27: begin { read } if eof(prd) then ps := redchk else case ir.y of 1: read(prd, s[s[t].i].i); 2: read(prd, s[s[t].i].r); 4: read(prd, s[s[t].i].c); end; t := t - 1 end; 次に procedure inter6; begin case ir.f of 60:..... ... ... 62: if eof(prd) then ps := redchk else readln; で全部だと思います。 wirthさんのソースにすごく似た箇所があったんですけど、 自分ではやはりわかりませんでした。。。 こんな断片でもわかりますでしょうか??
- sakusaker7
- ベストアンサー率62% (800/1280)
ひょっとして、自分で自分を記述している奴じゃないですか? だったらその本持ってますよ。 今は携帯端末でちまちまやってるんでちょっと時間をもらえれば 調べてみますよ。 いやあしかし懐かしいなあ。pascal-s。
お礼
ほんとですか!!ありがとうございます! 確か、本の名前は「プログラミング言語の処理系」って本です! Pascal-Sコンパイラのソースが、Pascalで書かれてるやつです!! ほんと申し訳ないのですが、よろしくおねがいしますm(_ _)m
- sakusaker7
- ベストアンサー率62% (800/1280)
read抜きでeofを呼んでいるのはresetによる ファイルの割り当てが成功しているのかを確認するためかもしれません。 読み込みをしないプログラムとのことですが、なにをする プログラムなのでしょうか? 問題がなければ補足でソースを張り付けてください。 リダイレクトが行われていなければ、標準入力はキーボード からの入力ですね。 あと、pascalコンパイラの起動コマンドとか、使っているOSは 何ですか?
お礼
このソースはPascal-Sコンパイラなんです。 僕の課題は、Pascal-SコンパイラをJavaで書き直すというものです。 このソースはUCSD Pascalだそうです。 このソースは本にのっているもので、自分自身起動したことはないんです。
- sakusaker7
- ベストアンサー率62% (800/1280)
そのへんはきちんと決まったところでないと思うので、具体的な処理系が わからないとなんとも言えませんが、 http://web.sfc.keio.ac.jp/~masudako/class/computer/filter/fileopen.html あたりをみたところでは 変数prdにコンソールか標準入力を割り当てようとしているのでは?
お礼
素早い回答ありがとうございます!標準入力とはキーボードのことですよね。 プログラムの途中、eof(prd)が出てくるのですが、read(prd)はでてこないんです、、 キーボードからの情報を一度も読み取らないのに、EOFかどうかを判定するというのはどういったことなんでしょうか・・? ちなみにこの処理系は標準Pascalではなかったと思います。 具体的にわからなくてすみません。。。
お礼
時間が空いてしまい申し訳ありません。 改行を入れたらできました! 自分なりに一度Javaで書いては見たんですけど、 やはり動きませんでした。。 もう少し自分でデバッグしてみます。。 書き込み側と読み込み側のつじつまが合う というのが申し訳ないのですがよくわかりません・・・ 具体的にどうすればいいのでしょうか?