前のページ 次のページ
プリプロセッサ、中間言語 投稿者:Misawa  投稿日: 4月19日(木)02時58分31秒

 こんにちわ、みさわと申します。
質問ですが、yacc で#include なんかのプリプロセッサ機能を付けた
いのですが、先読み等があるので動作に自信が持てません。出来れば、
手書きによるパーサは避けたいので、これに関する具体的解決策をお
持ちの方は宜しければお答え下さい。
 あと、アセンブラで処理するための簡単な中間コードについて考え
ているんですが、何か参考になる物はありませんでしょうか?

 どなたか是非お答え下さい。よろしくお願いします。

■Rrc(リソースコンパイラ)
 Vectorにてリソースコンパイラのテスト版を公開しました。
まだ、ぜんぜん出来ていませんがサンプルのコンパイルには多分、支
障は無いと思います。ソースコードも付いてますのでよろしければ、
ダウンロードしてみてください。
http://www.vector.co.jp/vpack/browse/person/an025978.html


とても初歩的な質問なんですけど・・。 投稿者:コアラ  投稿日: 4月15日(日)23時27分03秒

こんな質問してもいいかわからないんですけど、一人では解決出来ないのでみなさんにお聞きしたいと思います。私はゲームを作るためにC言語を勉強しようと思っているんですけど、C++とコンパイラの関係がわかりません。HPの場合ですと、ソースをブラウザで解読して、それを反映させますよね?とうことは、C++がソースということになりますよね?で、コンパイラとはなんなんですか?どうしても知りたいので、教えてください。


recursive descent 投稿者:なるなる  投稿日: 4月 7日(土)01時10分50秒

すいません。実は訳語が

「再帰降下」 だか 「再帰下降」 だか、いつもわからなくなるので、(間違えると恥ずかしいので) 英語のまま書いています。

普通に手で parser を書いた場合が、これになります。(PL/0 とか)

非終端記号に対応する関数を呼び出すことで解析が進んで行くので、このように呼ばれています。(直接再帰とは限りませんが式などを考えると通常再帰になります。)

もうひとつ、下向き解析でもテーブルを使って再帰せずに処理することができるので、区別するために「再帰」と強調するというのもあるようです。

(たとえば JavaCC は確か LL(1) だったような気が ... あと LL 系だと ANTLR というのも有名です。後で、いやになったらこっちに逃げてみてください。)

# お力になれませんが、いろいろ、頑張ってみてくださいね。


なるほど 投稿者:pangmer  投稿日: 4月 7日(土)00時40分09秒

yaccでは、単純な方法では無理というのが通説なんですか・・・
確かに、「もっと先読みして、期待している状態と違っていたら戻ってやり直し」できたら・・と
思うところが多々あるので、悩んでいます。

なるなるさんの仰るとおり、super setな文法で挑戦してみます。
しかし、本当に難しいです。
自分でもいろいろこじつけで、構文規則に追加していますが
何か追加するたびに、shift-reduceやreduce-reduceが発生しまくっています。
でも、挑戦しがいがあり試行錯誤が楽しいのでがんばってみます。

無知で申し訳ないのですが、recursive descent というのはどういったものなのでしょうか?


無責任なアイディア 投稿者:なるなる  投稿日: 4月 6日(金)23時54分52秒

C++ の parse ですが、いちおう常識では yacc じゃ無理ということになってますので、普通に知られている裏技だけでは難しいと思います。

確か厳密にはこれでも yaccable にはならないと、どこかで読んだ気がしますが

yacc で parse できない部分を parse 出来るように変更した C++ super set の文法を作るというのが、割とみんなが思いつく、次の手のようです。(ご存じかもしれません。)

# 下の例で言うと、クラスの C と C() を区別しなくてよいような文法をでっち上げる。ちなみに Roskind の文法には template は入っていなかったような ...

それで parse しておいて、意味チェックの段階で、本来の C++ の仕様からはみ出ているものをはじくわけです。

# これまた yaccable じゃない FORTRAN77 ですが、何十個もフラグのある yacc で書かれた FORTRAN77 parse というのもあるらしいです。

ただ、理論的には無限先読みが必要ということのようなので、最終的になんらかの back track は必要になるようです。

# 私は C++ 使っていない (汚い言語はいや) ので外してるかもしれませんけど。

ご参考までに


Re: C++ grammer 投稿者:なるなる (was とおり ..)  投稿日: 4月 6日(金)23時22分40秒

# すこし続きそうなので、他のところで使っているハンドルにしました。

> Stroustrupはどうしてあんな文法にしたのかしら。コンパイラ(プリプロセッサ)を作るときに不自由したと思うだけど。

The Design and Evolution of C++ (Addison Wesley) の 3.3.2 Parsing C++ (pp68-69) に、最終的に yacc を使わなかった理由が少し出ています。

# その部分の記述によると Cfront は 一時期 yacc で書かれていたようです。

x 自分が recursive descent に慣れていた

x recursive descent のほうがエラー回復が書きやすい

x その当時 C を yacc で parse する技術は知られていなかった。(ANSI C に最終的に採用された文法は、もう少し後で登場した。)

x (たぶん yacc で書かれていた) Johnson の PCC の印象が良くなかった。

ということのようです。

--だそく

私は parse 可能な文法を設計するという観点をあまり重視していなかったのではないかと「思っています」。

自分の作った parser が動けば良いということで、ad hoc に機能を足していった結果、気づいたときには妙な文法になっていた ?! のかなと妄想しております。

--

# 邦訳も出てたと思いますが、持ってないので ...

ご参考までに。


Re: C++ grammer 投稿者:pangmer  投稿日: 4月 6日(金)14時41分43秒

レスありがとうございます。
それなりに作ってはいるのですが、namespaceとtemplate、コンストラクタ、デストラクタ
で詰まっています。
識別子の解釈が非常に難しいです。
namespace B
{
  class C
  {
    C();
  };
}
namespace D
{
  class C
  {
    C();
  };
}
みたいな記述だと、クラス名C,C()の判別+templateなんかがはいると
凄く混乱してしまいます。(^^;;

J.Roskindさんのを参考にしてみます。


よしへさん、よかったですね 投稿者:徳丸 浩(オケゲム)  投稿日: 4月 6日(金)12時57分02秒

うまく動いたよし、よかったですね。
また、ちょくちょく遊びに来てください。


Re: C++ grammer 投稿者:徳丸 浩(オケゲム)  投稿日: 4月 6日(金)12時56分24秒

「とおりすがり」さん(?)、コメントをありがとうございます。
たしかにそのとおりですね。

Stroustrupはどうしてあんな文法にしたのかしら。コンパイラ(プリプロセッサ)を
作るときに不自由したと思うだけど。

bisonマニュアルの訳書はCopyleftだったような気もしますが、今手元にないので、
あらためて報告します。


どうもありがとうございます 投稿者:よしへ  投稿日: 4月 6日(金)12時31分42秒

ちゃんと動きました!!
ちょっとした間違いですが、かなり大きなミスだということがわかりました。
JavaScriptはちゃんと勉強しなくちゃだめですね
また何かあったら、相談しに来ますのでよろしくお願いします。


前のページ 次のページ