1 / 17

lex,yacc について

lex,yacc について. 2001 年 9 月 20 日 上牧瀬 誠. 宣言部. %%. ルール部. %%. プログラム部. lex. 字句解析プログラムを生成するプログラムジェネレータ lex.yy.c が生成. ルール部. 字句解析を行う パターンとアクションからなる パターンとアクションは同じ行に書く 入力がパターンにマッチしたときアクションが実行される. パターン. 入力文字の並び パターンは正規表現で書かれる 例 abc { アクション 1} de { アクション 2} 入力“ abcde” が与えられると,

triage
Télécharger la présentation

lex,yacc について

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. lex,yaccについて 2001年9月20日 上牧瀬 誠

  2. 宣言部 %% ルール部 %% プログラム部 lex • 字句解析プログラムを生成するプログラムジェネレータ • lex.yy.cが生成

  3. ルール部 • 字句解析を行う • パターンとアクションからなる • パターンとアクションは同じ行に書く • 入力がパターンにマッチしたときアクションが実行される

  4. パターン • 入力文字の並び • パターンは正規表現で書かれる • 例 abc {アクション1} de {アクション2} 入力“abcde”が与えられると, • “abc”を読みアクション1が実行 • “de”を読みアクション2が実行

  5. 正規表現で使われる記号 . 改行を除く任意の1文字にマッチ * 直前の正規表現の0回以上の繰り返しにマッチ + 直前の正規表現の1回以上の繰り返しにマッチ ? 直前の正規表現の0回か1回にマッチ | 直前の正規表現もしくは直後の正規表現にマッチ [] 角括弧で囲まれた文字のどれか1文字にマッチ ^ 正規表現の先頭にある場合は,行の先頭にマッチ 角括弧の中では否定の意味 $ 正規表現の最後にある場合は,行末にマッチ \ メタ文字をエスケープするために使用(\n:改行,\t:タブ,など) {} カッコ内に1つあるいは2つの数字を記述し,直前のパタンの繰り返し が何回現れるとマッチするか示す {3,} 3回以上 {,5} 5回以下 {3,5} 3回以上5回以下 “” 引用符の中の文字列そのものにマッチ / 「/」の直後の正規表現にマッチするような文字列の前にある場合のみ, 「/」の直前のパタンにマッチ () 正規表現の並びをグループ化

  6. lexで使われる主な変数 • yytext • パターンとマッチした文字列が格納されている変数 • yyleng • パターンとマッチした文字列の長さが格納されている変数 • yylval • 構文解析ルーチン(yaccプログラム)にトークンを返すときの付加情報を格納する変数

  7. 字句解析の例 abc ECHO; • パターンにマッチした文字列をそのまま出力 [0-9]+ printf(“number = %d\n”,atoi(yytext)); • マッチした文字列を数値に変換して,数値として出力 -?[0-9]+ {yylval = atoi(yytext); return (NUMBER);} • NUMBERの付加情報としてマッチした文字列を数値に変換 [a-zA-Z] retrun (CHAR); • アルファベット1文字にマッチしたらCHARを返す

  8. ECHO • fprintf(yyout,”%s”,yytext); と同値 yyoutは標準出力のファイルポインタ • NUMBER,CHAR • 構文解析ルーチン(yaccプログラム)で宣言されたトークン

  9. 宣言部 • 「%{」と「%}」で囲んで記述したCのコードを,lexは字句解析ルーチンにそのまま複写 ファイル読み込み,定数定義,変数宣言 • word [^ \n\t]+ • ルール部のパターンで{word}で参照できる {word} {yylval = yyleng; return (WORD);}

  10. プログラム部 • Cのプログラムを書く • 省略すると,デフォルトで次のmain()関数が書かれる int main() { yylex(); return 0; }

  11. 宣言部 %% ルール部 %% プログラム部 yacc • 構文解析プログラムを生成するプログラムジェネレータ • y.tab.cが生成

  12. 宣言部 • 「%{」と「%}」で囲んで記述したCのコードを,yaccは構文解析ルーチンにそのまま複写 • %tokenでトークン(終端記号)を宣言 %token NUMBER CHAR • %left,%right,%nonassocで優先順位の設定 下に書いてあるものほど優先順位が高い %left ‘+’ ‘-’ %left ‘*’ ‘/’ • %startでスタート規則を宣言,省略するとルール部の最初の規則がスタート規則

  13. ルール部 • 構文解析を行う • 規則とアクションからなる • 規則はLALR(1)文法で書かれる • アクションはCのプログラム S : A ‘+’ B {$$ = $1 + $3;} | C {printf(“%d\n”,$1);} ; S : A ‘+’ B $$ $1 $2 $3 $$,$1,...はそれぞれの 付加情報(yylaval)に対応

  14. lexプログラム例 %{ /******************************/ /* Simple Calculator (lex program) */ /******************************/ #include <stdio.h> %} %% “+” return (ADDOP); "-" return (SUBOP); "*" return (MULOP); "/" return (DIVOP); "(" return (LP); ")" return (RP); [0-9]+ {yylval = atoi(yytext); return (NUMBER);} [ \t] ; \n return (NL); . return (yytext[0]); %%

  15. yaccプログラム例 %{ /*******************************/ /* Simple Calculator (yacc program) */ /*******************************/ #include <stdio.h> %} %token NL NUMBER LP RP %left ADDOP SUBOP %left MULOP DIVOP %%

  16. yaccプログラム例(続き) s : list ; list : /* empty */ | list expr NL {printf("%d\n",$2);} ; expr : expr ADDOP expr {$$ = $1 + $3;} | expr SUBOP expr {$$ = $1 - $3;} | expr MULOP expr {$$ = $1 * $3;} | expr DIVOP expr {$$ = $1 / $3;} | LP expr RP {$$ = $2;} | NUMBER {$$ = $1;} ; %% #include "lex.yy.c"

  17. 実行例 % lex smpint.l yy.lex.cが生成 % yacc smpint.y y.tab.cが生成 % gcc y.tab.c –ly –ll –o scalc コンパイル % ./scalc 実行 (1+2)*3 入力 9 出力 ^D 終了 %

More Related