記号表の検索と登録 長谷川啓 2018.09.25.

Slides:



Advertisements
Similar presentations
Tt_clown ( 津川 知朗) 俺 Tokenizer を作る ~ Boost.Tokenizer のカスタマイズ~ 2009/12/121 Boost 勉強会.
Advertisements

2.5 プログラムの構成要素 (1)文字セット ① ASCII ( American Standard Code for Interchange ) JIS コードと同じ ② EBCDIC ( Extended Binary Coded Decimal for Information Code ) 1.
【事例演習5】  字句解析     解 説  “ハッシュを用いた字句解析の方法”.
アルゴリズムとデータ構造 第2回 線形リスト(復習).
Ex7. Search for Vacuum Problem
Ex8. Search for Vacuum Problem(2)
Javaのための暗黙的に型定義される構造体
データ構造とアルゴリズム 第10回 mallocとfree
プログラミング演習Ⅱ 第12回 文字列とポインタ(1)
第8回 プログラミングⅡ 第8回
アルゴリズムとデータ構造 2011年6月13日
構造体.
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
Linuxカーネルについて 2014/01.
第3回 配列,構造体,ポインタ ~ データ構造について学ぶための基礎~
第16章 構造体 16.1 構造体の定義と構造体変数 16.2 構造体の配列.
補足説明.
第10章 char 文字列; 文字列を入力させるよ!.
11.6 ランダムアクセスファイル 11.7 StreamTokenizerクラス
プログラミング論 関数ポインタ と 応用(qsort)
細かい粒度で コードの再利用を可能とする メソッド内メソッドと その効率の良い実装方法の提案
独習JAVA 6.8 コンストラクタの修飾子 6.9 メソッドの修飾子 6.10 ObjectクラスとClassクラス 11月28日(金)
暗黙的に型付けされる構造体の Java言語への導入
プログラミング 4 記憶の割り付け.
Nakano School of Business 経営情報ビジネス科 【 Java概論(Test5)】
アルゴリズムとプログラミング (Algorithms and Programming)
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
第11回 プログラミングⅡ 第11回
P n ポインタの基礎 5 q m 5 7 int* p; int 型の変数を指すポインタ int* q; int 型の変数を指すポインタ int n=5, m=7; int 型の変数 int array[3]; int* pArray[3]; p = &n; ポインタにアドレスを代入しているのでOK.
データ構造と アルゴリズム 第五回 知能情報学部 新田直也.
一時的な型 長谷川啓
Ex7. Search for Vacuum Problem
フロントエンドとバックエンドのインターフェース
型の compatibility とポインタ演算
オブジェクト指向プログラミングと開発環境
コンパイラ 2011年10月20日
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
アルゴリズムとプログラミング (Algorithms and Programming)
C++ 構文解析 構文解析器の状態保存と復元
参照されないリテラル 長谷川啓
東京工科大学 コンピュータサイエンス学部 担当 亀田弘之
プログラミングⅡ 第2回.
C#プログラミング実習 第3回.
コンパイラ 2012年10月29日
アルゴリズムとデータ構造 2012年6月11日
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
ドキュメントジェネレータ 詳細仕様 長谷川啓
extern の意味 (C プログラミング演習,Visual Studio 2019 対応)
X64 函数呼び出し規約 長谷川啓
コンパイラ 2012年10月11日
プログラミング 4 文字列.
Inline 展開のアルゴリズム 長谷川啓
フレンド関数とフレンド演算子.
演算子のオーバーロード.
Tacsim の実装 - 実行部分 長谷川啓
プログラミング演習I 2003年6月11日(第9回) 木村巌.
:: の扱い 長谷川啓.
プログラミング言語論 第九回 理工学部 情報システム工学科 新田直也.
ドキュメントジェネレータ doclink 設計メモ
オブジェクト指向言語論 第三回 知能情報学部 新田直也.
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
プログラミング演習II 2003年12月10日(第7回) 木村巌.
左右反転と180度回転 [0][xsize – 1] [0][0] → i ↓ j [ysize – 1][xsize – 1]
プロジェクト演習III,V <インタラクティブ・ゲーム制作> プログラミングコース
C言語講座第5回 2017 構造体.
デフォルト引数 長谷川啓.
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
俺 Tokenizer を作る ~Boost.Tokenizer のカスタマイズ~
Presentation transcript:

記号表の検索と登録 長谷川啓 2018.09.25

プログラムに出現する変数、リテラルの扱い struct scope { ... map<string, vector<usr*> > usrs; // 名前からシンボル情報にアクセスする };

map<string, vector<usr*> > // 函数の外側 int i = 1; int i; // ok extern int i; // もちろん ok map<string, usr*> ではなく map<string, vector<usr*> > にしているのはこういう理由から

バックエンドの記号表に対する扱い int i = 1; // (1) int i; // (2) extern int i; // (3)

フロントエンドの記号表 lookup // 文字列に対して記号表を検索して字句の種別を返す函数 lex::kind_t lookup(string name, scope* ptr) { const map<string, vector<usr*> >& usrs = ptr->usrs; map<string, vector<usr*> >::const_iterator p = usrs.find(name); if ( p != usrs.end() ) { const vector<usr*>& v = p->second; usr* u = v.back(); // ポイント : 最後の宣言を参照する ... } int i = 1; // (1) int i; // (2) extern int i; // (3) void f(void){ ... use i ... } // 参照するのは (3) の宣言

バックエンドの記号表に対する扱い(その2) 函数 gen で (1) に対して初期値ありのコードを生成 (2) に対して初期値なし(スペースのみ)のコードを生成 (3) は extern があるからスキップ とするのは i の多重定義になるので間違い。 find_if(v.begin(), v.end(), gen); のようにすれば(1)でのコード生成のみで一応大丈夫 int i = 1; // (1) int i; // (2) extern int i; // (3) バックエンドの実装 const map<string, vector<usr*> >& usrs = ... for_each(usrs.begin(), usrs.end(), usr); void usr(const pair<string vector<usr*> >& p) { const vector<usr*>& v = p.second; for_each(v.begin(), v.end(), gen); }

バックエンドでの記号表の扱い(その3) int i = 1; // (1) int i; // (2) void f(void){ ... use i ... } // (1) でなく (2) を参照. (2) の i のアドレス記述子をちゃんと決めてあげないといけない extern int i; void g(void){ ... use i ... } // (1) でも (2) でもなく (3) を参照. 宣言に対するコード生成とは別に、アドレス記述子は最後の宣言に対して決める必要がある。 const vetor<usr*>& v = p.second; find_if(v.begin(), v.end(), gen); decide_address_descriptor(v.back()); のようにする必要がある。

フロントエンドでの記号表への登録 void install(usr* curr, scope* ptr) { string name = curr->m_name; map<string, vector<usr*> >& usrs = ptr->m_usrs; map<string, vector<usr*> >::iterator p = usrs.find(name); if ( p != usrs.end() ) { vector<usr*>& v = p->second; usr* prev = v.back(); // 直前の宣言のみと比較する if (!prev->m_type->compatible(curr->m_type) || ... ) { // 再宣言されている。エラー。 } else { curr->m_type = prev->m_type->composite(curr->m_type); usrs[name].push_back(curr);

例 void f(); // void (...) として登録 void g() { } f(1,2,3); // ok } void f(int); // ok. void (...) と void (int) は compatible なので // composite な void (int) として登録 void h() { f(3); f(1,2,3); // エラー void f(); // もう一回! void (int) と void (...) は compatible なので void i() { f(1,2,3); // これはエラー