1.文法G(S):
(1)S - > AB
(2)A - >ダ|ε
(3)B - > CC
(4)C - > AADC |ε
(5)D - > B |ε
文法G(S)は、LL(1)文法ではない検証?
FIRST集:
FIRST(DA)= {B}
FIRST(E)= {E}
FIRST(AADC)= {}
FIRST(B)= {B}
FOLLOW集:
FOLLOW(A)= {C、B、#}
フォロー(C)= {#}
フォロー(D)= {#}
SELECTセット:
SELECT(A->ダ)= FIRST(DA)= {B}
SELECT(A->ε)= FIRST(ε) - {ε} UFOLLOW(A)= FOLLOW(A)= {C、B、#}
ソリューション:
SELECT(A-> Da)で∩SELECT(A->ε)≠Ø
これは、G(S)はLL(1)構文ではないことがわかりました。
式の文法は、LL(1)文法であるかどうか、左再帰を除去した後2.(最後のジョブ)?
左再帰を排除します:
E - > TE "
E ' - > + TE' | E
T - > FT」
T ' - > * FT' | ε
F - >(E)| 私
FIRST集:
FIRST(TE ')= {(I}
FIRST(+ TE ')= {+}
FIRST(E)= {E}
FIRST(FT ')= {(I}
FIRST(* FT ')= {*}
FIRST((E))= {(}
FIRST(I)= {I}
FOLLOW集:
フォロー(E)= {)、#}
フォロー(E ')= {)、#}
フォロー(T)= {+、)、#}
フォロー(T ')= {+、)、#}
フォロー(F)= {+、*、)、#}
SELECTセット:
SELECT(E-> TE ')=最初の(TE')= {(I}
SELECT(E ' - > + TE')=最初の(+ TE ')= {+}
SELECT(E ' - > E)=最初の(E) - {E} UFOLLOW(E')=フォロー(E「)= {)、#}
SELECT(T-> FT ')=最初の(FT')= {(I}
SELECT(T ' - > * FT')=最初の(* FT ')= {*}
SELECT(T ' - >ε)= FIRST(ε) - {ε} UFOLLOW(T')=フォロー(T ')= {+、)、#}
SELECT(F - >(E))= FIRST((E))= {(}
SELECT(F-> I)=最初の(I)= {I}
ソリューション:
SELECT(E ' - > + TE')∩SELECT(E「 - >ε)= O
SELECT(T ' - > * FT')∩SELECT(T ' - >ε)= Oで
SELECT(F - >(E))∩SELECT(F-> I)= Oで
したがって、左再帰式文法を除去した後、LL(1)文法です。
それは、LL(1)文法であれば3接続2、その再帰下降構文解析コードを書きます。
E()
{T();
E '();
}
E '()
T()
T '()
F()
コード:
ボイドパーシー(){
スイッチ(ルックアヘッド){
ケース '('、 'I'、 '*':
Frset();
ParseEP();
ブレーク;
デフォルト:
印刷( "syntxエラー\ nは!");
出口(0);
}
}
ボイドParseEP(){
スイッチ(ルックアヘッド){
場合 '+':
マッチトークン( '+');
Frset();
ParseEP();
ブレーク;
ケース '#'、 ')':
ブレーク;
デフォルト:
印刷( "syntxエラー\ nは!");
出口(0);
}
}
ボイドPARSET(){
スイッチ(ルックアヘッド){
ケース '('、 'I':
ParseF();
ParseTP();
ブレーク;
デフォルト:
印刷( "syntxエラー\ nは!");
出口(0);
}
}
ボイドParseTP(){
スイッチ(ルックアヘッド){
ケース '*':
マッチトークン( '*');
ParseF();
ParseTP();
ブレーク;
ケース '#'、 ')'、 '+':
ブレーク;
デフォルト:
印刷( "syntxエラー\ nは!");
出口(0);
}
}
ボイドParseF(){
スイッチ(ルックアヘッド){
ケース '(':
マッチトークン( '(');
パーシー();
マッチトークン( ')');
ブレーク;
ケース 'I':
マッチトークン(「中」);
ブレーク;
デフォルト:
印刷( "syntxエラー\ nは!");
出口(0);
}
}
字句解析を追加4.実験では、パーサは、任意の入力記号列が有効な式ではありません分析し、実行を形成することができます。