• 検索結果がありません。

• 

何をトークンとして扱うか

 

– 

終端記号はすべてトークン

 

– 

基本言語仕様のうち正規表現で書けるものは トークンとして

lex

で切り出す

基本言語仕様

<プログラム> ::= <変数宣言部> <文集合>

<変数宣言部> ::= <宣言文> <変数宣言部> | <宣言文>

<宣言文> ::= define <識別子>; | array <識別子> [<数>];

<文集合> ::=  <文> <文集合>| <文>

<文> ::= <代入文> | <ループ文> | <条件分岐文>

<代入文> ::= <識別子> = <算術式>;  <識別子> [ <数> ] = <算術式>;

<算術式> ::= <算術式> <加減演算子> <項> | <項>

<項> ::= <項> <乗除演算子> <因子> | <因子>

<因子> ::= <変数> | (<算術式>)

<加減演算子> ::= + | -

<乗除演算子> ::= * | /

<変数> ::= <識別子> | <数> | <識別子>[<数>]

<ループ文> ::= while (<条件式>) { <文集合> }

<条件分岐文> ::= if (<条件式>) { <文集合> } | if (<条件式>) { <文集合> } else { <文集合> }

<条件式> ::= <算術式> <比較演算子> <算術式>

<比較演算子> ::= == | '<' | '>'

<識別子> ::= <英字> <英数字列> | <英字>

<英数字列> ::= <英数字> <英数字列>| <英数字>

<英数字> ::= <英字> | <数字>

<数> ::= <数字> <数> | <数字>

<英字> ::= a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|

T|U|V|W|X|Y|Z

<数字> ::= 0|1|2|3|4|5|6|7|8|9

この線から下は

lex

基本言語仕様

<プログラム> ::= <変数宣言部> <文集合>

<変数宣言部> ::= <宣言文> <変数宣言部> | <宣言文>

<宣言文> ::= define <識別子>; | array <識別子> [<数>];

<文集合> ::=  <文> <文集合>| <文>

<文> ::= <代入文> | <ループ文> | <条件分岐文>

<代入文> ::= <識別子> = <算術式>;  <識別子> [ <数> ] = <算術式>;

<算術式> ::= <算術式> <加減演算子> <項> | <項>

<項> ::= <項> <乗除演算子> <因子> | <因子>

<因子> ::= <変数> | (<算術式>)

<加減演算子> ::= + | -

<乗除演算子> ::= * | /

<変数> ::= <識別子> | <数> | <識別子>[<数>]

<ループ文> ::= while (<条件式>) { <文集合> }

<条件分岐文> ::= if (<条件式>) { <文集合> } | if (<条件式>) { <文集合> } else { <文集合> }

<条件式> ::= <算術式> <比較演算子> <算術式>

<比較演算子> ::= == | '<' | '>'

<識別子> ::= <英字> <英数字列> | <英字>

<英数字列> ::= <英数字> <英数字列>| <英数字>

<英数字> ::= <英字> | <数字>

<数> ::= <数字> <数> | <数字>

<英字> ::= a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|

T|U|V|W|X|Y|Z

<数字> ::= 0|1|2|3|4|5|6|7|8|9

具体的には赤字がトークン

 

あとはこの線より上の終端記号がトークン

トークン

• 

それぞれのトークンごとに種類を分ける

 

例:識別子,数,プラス記号,マイナス記号,

define,  array  ….  

• 

今はまだ

yacc

のアクションを書かないので型 について考える必要はない

 

•  lex

もトークンの名前を

return

するだけでよい

非終端記号の名前  

(本来なんでもいいのだが,時間がないので例を示す)

<

プログラム

> program

<

変数宣言部

> declarations

<

宣言文

> decl_statement

<

文集合

> statements

<

> statement

<

代入文

> assignment_stmt

<

算術式

> expression

<

> term

<

因子

> factor

<

加減演算子

> add_op

<

乗除演算子

> mul_op

<

変数

> var

<

ループ文

> loop_stmt

<

条件分岐文

> cond_stmt

<

条件式

> condition

<

比較演算子

> cond_op

基本言語仕様にあるそれ以外 の非終端記号は

lex

で処理して トークンになってしまうので

yacc

ファイルでの非終端記号として は扱わない

言語仕様を拡張してこれ以外 の非終端記号を導入するとき はその名前は自分たちで考え ること

これらの名前を

yacc

ファイルで 使う

トークン名 ( 普通は大文字を使う)  

(本来なんでもいいのだが,時間がないので例を示す.)

define DEFINE

array ARRAY

while WHILE

if IF

else ELSE

; SEMIC

[ L_BRACKET

] R_BRACKET

( L_PARAN

) R_PARAN

{ L_BRACE

} R_BRACE

= ASSIGN

+ ADD

- SUB

* MUL

/ DIV

== EQ

< LT

> GT

<識別子> IDENT

<数> NUMBER

言語仕様を拡張してこれ以外 のトークンを導入するときはそ の名前は自分たちで考えるこ

これらが

lex

からの

return

値に

なる

lex   ファイル(ひながた)

(

定義部省略)

 

%%  

"define"                return  DEFINE;                                                                                                    

"array"                  return  ARRAY;  

…(

中略

)…  

整数の正規表現 

return  NUMBER;  

識別子の正規表現 

return  IDENT;  

空白タブ改行     

;  

%%  

• 

省略されている定義部と 規則部の部分を書くこと

 

• 

赤字のところを正規表現 に直すこと

yacc ファイル(ひながた)

…(

)…  

%token  DEFINE  ARRAY  WHILE  IF  ELSE  

以下トークンを全て

%token

で定義

 

%%  

program  :  declaraxons  statements  

;  

declaraxons  :  decl_statement  declaraxons  |  decl_statement  

;   decl_statement  :  DEFINE  IDENT  SEMIC  

関連したドキュメント