B演習(言語処理系演習)第3回 字句解析 田浦.

Slides:



Advertisements
Similar presentations
2.5 プログラムの構成要素 (1)文字セット ① ASCII ( American Standard Code for Interchange ) JIS コードと同じ ② EBCDIC ( Extended Binary Coded Decimal for Information Code ) 1.
Advertisements

プロセスの生成とコマンドの実行 プロセスの生成とコマンドの実行 プロセス生成のシステムコール プロセス生成のシステムコール プロセス生成のプログラム例 プロセス生成のプログラム例 プログラム実行のシステムコール プログラム実行のシステムコール 子プロセスの終了を待つシステムコール 子プロセスの終了を待つシステムコール.
オブジェクト指向言語・ オブジェクト指向言語演習 中間試験回答例. Jan. 12, 2005 情報処理技術基礎演習 II 2 オブジェクト指向言語 中間試験解説 1  (1) 円柱の体積(円柱の体積 = 底面の円の面積 x 高さ) を求めるプログラムを作成しなさい。ただし、出力結果は、入 力した底面の円の半径.
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
コンパイラ 2011年10月17日
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
1.1 C/C++言語 Hello.ccを作りコンパイルしてa.outを作り出し実行する
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
12.3,E,-15, 12.3,E5,+,=, >,<,…,
システムプログラミング 第5回 情報工学科 篠埜 功 ヒアドキュメント レポート課題 main関数の引数 usageメッセージ
プログラミング基礎I(再) 山元進.
第2回ネットワークプログラミング 中村 修.
OSとコマンド OS:コンピュータを使うための基本プログラム コマンド:OS上で使用できる命令 OS本体であるカーネルの内部コマンド
第13回 プログラミングⅡ 第13回
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
12: コマンドライン引数 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
プログラミング演習II 2004年12月 21日(第8回) 理学部数学科・木村巌.
プログラミング論 II 電卓,逆ポーランド記法電卓
アルゴリズムとデータ構造 補足資料6-3 「サンプルプログラムcat3.c」
コンパイラ 2012年10月15日
精密工学科プログラミング基礎 第9回資料 (12/11 実施)
第20章 Flyweight ~同じものを共有して無駄をなくす~
関数 関数とスタック.
構造体 構造体, 構造体とポインタの組み合わせ,.
11.6 ランダムアクセスファイル 11.7 StreamTokenizerクラス
ちょっとした練習問題① 配列iroを['R', 'W', 'R', 'R', 'W' , 'W' , 'W']を宣言して、「W」のときの配列の番号をprintfで表示するようなプログラムを記述しなさい。
プログラムの制御構造 選択・繰り返し.
岩村雅一 知能情報工学演習I 第11回(後半第5回) 岩村雅一
Cプログラミング演習 中間まとめ2.
B演習(言語処理系演習)第8回 評価器 田浦.
FlexとBison+アルファ -実習編-
Cプログラミング演習.
電気・機械・情報概論 VBAプログラミング 第2回 2018年7月2日
Cプログラミング演習 第7回 メモリ内でのデータの配置.
iioLoadFile()とiioMallocImageBuffer()の補足
iioLoadFile()とiioMallocImageBuffer()の補足
アルゴリズムとプログラミング (Algorithms and Programming)
デバッガ dbx の使い方.
プログラミング演習I 2003年5月7日(第4回) 木村巌.
B演習(言語処理系演習)第4回 田浦.
プログラミング入門2 第11回 情報工学科 篠埜 功.
indentについて forやifの「中身」を右に寄せる. forやifの「外枠」は右に寄せない. int x; x = 3;
岩村雅一 知能情報工学演習I 第10回(後半第4回) 岩村雅一
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
実践ロボットプログラミング LEGO Mindstorms EV3 で目指せロボコン!
東京工科大学 コンピュータサイエンス学部 亀田弘之
プログラミング基礎B 文字列の扱い.
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
2005年度 データ構造とアルゴリズム 第6回 「ハッシュ法を用いた探索」
精密工学科プログラミング基礎Ⅱ 第4回資料 今回の授業で習得してほしいこと: 文字列の扱い ファイル入出力の方法 コマンドライン引数の使い方
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
B演習(言語処理系演習)第2回 田浦.
C++ 構文解析 構文解析器の状態保存と復元
ファイルの読み込み, ファイルからのデータの取り出し, ファイルの書き出し
12: コマンドライン引数 C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページを開いておく こと
情報処理Ⅱ 第2回 2005年10月14日(金).
情報処理Ⅱ 第2回 2006年10月13日(金).
ネットワーク・プログラミング Cプログラミングの基礎.
高度プログラミング演習 (11).
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
コンパイラ 2012年10月11日
プログラミング 4 文字列.
岩村雅一 知能情報工学演習I 第10回(後半第4回) 岩村雅一
プログラミング演習I 2003年6月11日(第9回) 木村巌.
第3回簡単なデータの入出力.
情報処理Ⅱ 小テスト 2005年2月1日(火).
プログラミング入門2 第3回 条件分岐(2) 繰り返し文 篠埜 功.
分岐(If-Else, Else if, Switch) ループ(While, For, Do-while)
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
12: コマンドライン引数 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
Presentation transcript:

B演習(言語処理系演習)第3回 字句解析 田浦

今日の予定 字句解析インタフェース 字句の定義 字句解析器の仕組み(概要) まめ知識: デバッガ デバッグに関する若干の抽象論 今週の課題 下請け部品 char_buf, char_stream, int_stack まめ知識: デバッガ デバッグに関する若干の抽象論

字句解析器とは 字句解析器 ‘d’ ‘e’ ‘f’ ‘ ’ ‘f’ ‘i’ ‘b’ ‘(’ ‘n’ ‘)’ ‘:’ (tokenizer) Identifier (n) ( identifier (fib) def

今週の課題 字句解析器の作成とそのテスト テストプログラム: ファイルから字句を読み出して,読み出された字句をその順に表示 表示の仕方 TOK_KW_FOR TOK_LITERAL_INT (35) TOK_ID (x) etc. テストデータとその正解があるのでそれを用いて比較

インタフェース tokenizer_t t = mk_tokenizer(char * filename); void tok_next(tokenizer_t t); 次の1字句を読み込んで現在の字句に設定 token_kind_t tok_cur_token_kind(tokenizer_t t); int        tok_cur_token_int_val(tokenizer_t t); double     tok_cur_token_float_val(tokenizer_t t); char *     tok_cur_token_str_val(tokenizer_t t); 現在の字句に関する情報を返す

インタフェース(2) 正しくエラーメッセージを表示するためのインタフェース char * tok_cur_token_string(tokenizer_t t); 現在構築中の字句の文字列表現 char * tok_cur_line_string(tokenizer_t t); 現在の行の文字列表現(現在の字句まで) そのほか2, 3 (資料参照)

字句解析器のテストプログラム int tokenizer_test(char * filename) { tokenizer_t t = mk_tokenizer(filename); while (tok_cur_token_kind(t) != TOK_EOF) { print_cur_token(t); tok_next(t); } return 0; }

void print_cur_token(tokenizer_t t) { char void print_cur_token(tokenizer_t t) { char * C_name = tok_cur_token_kind_string(t); switch(tok_cur_token_kind(t)) { case TOK_ID: case TOK_LITERAL_INT: case TOK_LITERAL_FLOAT: case TOK_LITERAL_STRING: printf("%s (%s)\n", C_name, tok_cur_token_string(t)); break; default: printf("%s\n", C_name); break; } }

int main(int argc, char. argv) { if (argc int main(int argc, char ** argv) { if (argc != 2) { fprintf(stderr, "usage : %s filename\n", argv[0]); exit(1); } else { tokenizer_test(argv[1]); exit(0); } }

字句の種類 テキスト,HP参照 or, and, is, not, in, =, ==, !=, >, >=, <, <=, +, -, *, /, %, ~, <<, >>, ^, &, |, None, break, continue, pass, return, del, print, global, if, elif, else, for, while, def, (, ), {, }, [, ], ., ,, :, integer, floatnumber, stringliteral, identifier newline, indent, dedent, end_of_file

少し複雑な字句 integer floatnumber string literal (エスケープ文字の扱い) identifier 0 | (1|…|9)(0|…|9)* floatnumber (0|…|9)+.(0|…|9)* | .(0|…|9)+ string literal (エスケープ文字の扱い) ”(x | \y)*” identifier (a|_)(a|d|_)* テキストおよびmini-Pythonの文法を参照

注意の必要な字句 end_of_file : 入力終端に達すると生成される newline : 改行に対して生成される(無視しない) 字下げ: indent : 字下げを1レベル深くする字句 dedent : 字下げを1レベル浅くする字句 コメント

字下げ/改行字句生成の例 def fib(n): if n < 2: return 1 else: return fib(n-1) + fib(n-2) def another_fun(…) …       改行  字下げ(indent)  逆字下げ(dedent)

コメント 基本: #から改行手前までを無視 行が空白とコメントのみの場合,改行も無視 例: x = y + z # calc x id(x), =, id(y), +, id(z), newline # calc x first x = y # then p p = q id(x), =, id(y), newline, id(p), =, id(q), newline

字句の種類のCプログラムでの定義 typedef enum { TOK_OR, /* or */ TOK_AND, /* and */ …, …, TOK_ID, TOK_NEWLINE, TOK_INDENT, TOK_DEDENT, TOK_EOF } token_kind_t;

字句のCプログラム内での定義 typedef struct token { token_kind_t k;   union { char * s_val; /* id, 文字列リテラル */ double f_val; /* 浮動小数点数リテラル */ int i_val; /* 整数リテラル */ } v; } token, * token_t;

字句解析器の基本的な仕組み 「現在の文字」に基づく場合わけ tok_next(tokenizer_t t) { … switch (現在の文字) { case ’%’ : t->tok.k = …; break; case ’0’..’9’ : t->tok.k = …; break; } … }

いくつかややこしいところ 各種literalとidentifier (正規表現) コメントの読み飛ばし indent/dedent字句の生成 現在構築中の行,字句の保持(エラーメッセージ用)

いきなりだとどうしていいか悩んでしまう人は, newline/indent/dedent 字句を後回しにする エラーメッセージ表示(そのための状態管理)を後回しにする tok_nextの主要部分(次の文字で場合わけをしながら,字句の切れ目まで読んでいく.読んだtokenをtokにセットする)に集中

有用な下請け部品 char_stream_t char_buf_t int_stack_t 文字を読み出すための下請け部品 ファイル名,行番号,列番号,現在行(現在の文字まで)を維持 char_buf_t 文字をためるバッファ(append) cur_line, cur_token_string, string literalの読み込み用 int_stack_t 整数のスタック indent/dedent用 先週からの拡張

デバッグの心構え いけないこと よい心構え 平常心を失うこと(「なぜ動かないんだっっ!!」) バグが消えてほしいと思うこと プログラムをむやみにいじること(うまく動けばラッキー,という考え方) よい心構え 目の前の(バグ入り)プログラムの動作を理解・観察・追跡する

実践的心構え 極力小さな入力でバグを再現する (できるだけ小さな入力で),どこまでまともに動作し,どこから狂いだすかを追跡する どんな入力なら動いて,どんな入力は動かないか? (できるだけ小さな入力で),どこまでまともに動作し,どこから狂いだすかを追跡する printfで変数の値を表示 デバッガ

「デバッガ」の使い方よりも大切な 「デバッグ」の方法 平常心 プログラムを直そうとやっきにならない 大切な心構え 目の前にあるプログラムの挙動の調査 どこで「本来の挙動」を逸脱したかの調査 本来の挙動 異常観測地点 プログラム開始時点 実際の挙動

デバッガ プログラムを実行 実行途中で停止 停止した状態で,変数,その他の「状態を観察」 関数先頭,行番号 ステップ(1行ずつ)実行 変数の値 関数呼び出しの履歴(なぜ今ここにいるか)

起動方法 gcc –g … (shell)% gdb プログラム名 (emacs) M-x gdb

まめ知識: gdbの良く使うコマンド r コマンドライン引数… p bt b 関数名 b ファイル名:行番号 (Emacs: C-x SPACE) c n s disp <RET>で最後のコマンドの繰り返し

メモリ割り当てについて よく分からない人はmalloc (C++ではnew)が基本と思っておく tokenizer_t mk_tokenizer() { tokenizer_t t   = (tokenizer_t)malloc(sizeof(tokenizer)); if (t == 0) { … exit(1); } t-> … = …; … return t; } tokenizer_t mk_tokenizer() { tokenizer t[1]; t->… = …; … return t; }

M-x info Cut & paste (コピペ) M-x query-replace M-x replace-string C-SPACE … C-w C-y M-x query-replace M-x replace-string キーボードマクロ