質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

コンパイラ

コンパイラは、プログラミング言語で記述したソースコードを、コンピュータの実行形式であるオブジェクトコードに変換するプログラムです。

Q&A

解決済

2回答

2017閲覧

プログラミング言語を構文木でパースする際goto文はどう処理すればよいか

ElecDove

総合スコア254

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

コンパイラ

コンパイラは、プログラミング言語で記述したソースコードを、コンピュータの実行形式であるオブジェクトコードに変換するプログラムです。

0グッド

0クリップ

投稿2021/05/06 08:13

編集2021/05/06 13:10

自作言語のコンパイルを考えています。(コンパイル以前に構文解析で躓いています)

何も考えずに、先頭からソースを読み、再帰的にパースしていたのですが、goto文の扱いに困ってしまいました。(あとから構文木という言葉を知りました。たぶん構文木だと思います)。C#で構文解析をする想定です。

例えば、if(A){B}else{C}なら、Aを必ず実行してその結果BまたはCを実行する、といった具合にパースできたのですが、goto文をパースしようと思ったときに脈絡のない場所にジャンプできてしまうためどうすればよいかわからなくなりました

if, while(for), break, continue, 四則演算, この辺りはどれもクラスで表すことができ、パースしながらオブジェクト化しています。実際の実装は、オブジェクト指向の練習を兼ねて、足し算クラス、条件分岐クラスなどなど…で実装してみました。
↓にイメージを載せます。

C#

1//基底クラス 2abstract class baseClass{ 3 public virtual returnObj Exec(); //構文を実行する 4} 5 6//複数の処理を連続して行うだけのクラス 7class Sequence: baseClass{ 8 public List<baseClass> seq; 9 public override Exec(){ 10 foreach(s in seq) s.Exec(); //順に実行する 11 } 12} 13 14//足し算をするクラス 15class Add: baseClass{ 16 public int left, right; 17 public override returnObj Exec(){ 18 return left + right; 19 } 20} 21 22//条件分岐をするクラス 23class If: baseClass{ 24 public baseClass ConditionalObj; //条件を指定 25 public baseClass trueObj;   //↑がtrueのとき実行 26 public baseClass falseObj;  //↑がfalseのとき実行 27 28 public override returnObj Exec(){ 29 if(ConditionalObj.Exec()){ 30 trueObj.Exec(); 31 }else{ 32 falseObj.Exec(); 33 } 34 } 35} 36 37//画面に表示するクラス 38class Print: baseClass{ 39 public returnObj printObj; 40 public override returnObj Exec(){ 41 Console.write(printObj); 42 } 43}

「goto文は処理の流れを無視する構文だ」という言葉の意味がよくわかりました。
既存のコンパイラがgoto文をどのように解析?処理?しているのかヒントを教えていただけないでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2021/05/06 08:50

tagが C になってるけど C# のまちがい?
ElecDove

2021/05/06 13:10

ありがとうございます。修正しました
guest

回答2

0

ベストアンサー

既存のコンパイラがgoto文をどのように解析?処理?しているのか

例えば MetaJC++: A flexible and automatic program transformation technique using meta framework の §4.4. Goto Statement に一例があります。

AST(抽象構文木)上の表現としては、ジャンプ先のラベルノード(と後続命令AST)と、goto命令ノードとジャンプ先ラベル情報をそれぞれ持てばよいはずです。


if, while(for), break, continue, 四則演算, この辺りはどれもクラスで表すことができ、パースしながらオブジェクト化しています。

質問文からはソースコードからASTを構築するフェーズ(Lexer/Parser)と、そのASTを解釈実行(Interpreter)するフェーズを混同している印象を受けました。

自作言語とのことですから、そもそもC言語のような非構造化ジャンプを許すgoto構文をサポートする必要性があるかを再検討してもよいかもしれませんね。

投稿2021/05/06 08:49

yohhoy

総合スコア6191

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ElecDove

2021/05/06 13:11

回答ありがとうございます。 いただいたリンク先をよく読んでみます >>質問文からはソースコードからASTを構築するフェーズ(Lexer/Parser)と、そのASTを解釈実行(Interpreter)するフェーズを混同している印象を受けました。 ありがとうございます。ここから見直してみます
yohhoy

2021/05/07 00:27 編集

リンク先はあくまでASTとgoto構文の関係例示のために取り上げただけですので、まずは一般的なコンパイラやインタプリタ(=プログラミング言語処理系)がどのように作られ・動作するのかを調べた方が良いと思います。 例えば下記サイトなどが参考になるかも? C#で作るインタプリタ https://webbibouroku.com/gorilla-interpreter (質問文には"コンパイラ"とありますが、実現したい内容を見るに"インタプリタ"が近いと思います)
ElecDove

2021/05/07 11:07

ありがとうございます まだ読み始めたばかりですがまさに自分にぴったりの内容のように思えます 感謝です
guest

0

C言語にはクラスというものがないので、そこまで難しく考えなくていいかと思いますが

投稿2021/05/06 08:27

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問