本プログラムでは、記述した拡張BNF記法がLL1であるかを判定する。
出力結果は以下の通りである。
- 正常にLL1判定を行うため、元の拡張BNFから変更を行った拡張BNF
- First集合
- Follow集合
- Director集合
- エラー又は訂正を行った内容
- 判定結果
なおマルチバイトには非対応である。
拡張BNF記法の記述方法として、以下の記述ルールを適用する。
"ε"がマルチバイトなの本当に許さんからな
- 終端記号及び非終端記号は、半角英数字とアンダーバーからなる
- 空文字は、"~"によって表現される
- 等式については、"::="によって結ばれる
- コメントは、";"以降に記述する
- 「または」は、"|"によって表現される
- 1回の繰り返しは、"("と")"で囲む
- 0回以上の繰り返しは、"{"と"}"で囲む
- 0回または1回の繰り返しは、"["と"]"で囲む
- "(", "{", "["と"]", "}", )"で囲んだ場合、"|"は囲んだ中で適用される
- 特殊文字は、空白文字によって分けなくても自動で判別する
- 出力する際、Follow集合が空である場合には"$"をFollow集合とする
2017/09/06現在、javac時に警告が出力される。
2018/11/28、Pull Requestをmergeし、警告が出力されないようになりました。ありがとうございます。
git clone git://github.com/who3411/isLL1.git
cd isLL1
mkdir out
javac -d out -encoding UTF-8 -sourcepath src src/isLL1/LL1Check.java
java -classpath out isLL1.LL1Check /path/to/EBNF/file
※/path/to/EBNF/fileの部分は、各自適切な拡張BNFが記述されたファイルのパスを入力
以下に4つの実行例を載せる。それぞれ次の場合の実行結果である。
- LL1である場合(testcase/test1.txt)
- warningが発生かつLL1である場合(testcase/test2.txt)
- LL1でない場合(testcase/test3.txt)
- エラーが発生する場合(testcase/test4.txt)
CODE ::= { LINE } EOF
LINE ::= [ TEST ] NL
TEST ::= INST PARAM LOOP | END
LOOP ::= COMMA PARAM LOOP | ~
CODE ::= { LINE } EOF
LINE ::= [ TEST ] NL
TEST ::= INST PARAM LOOP | END
LOOP ::= COMMA PARAM LOOP | ~
First(CODE) = {EOF, NL, INST, END}
First(LINE) = {NL, INST, END}
First(TEST) = {INST, END}
First(LOOP) = {COMMA, ~}
Follow(CODE) = {$}
Follow(LINE) = {EOF}
Follow(TEST) = {NL}
Follow(LOOP) = {NL}
Director(CODE, { LINE } EOF) = {NL, INST, END, EOF}
Director(LINE, [ TEST ] NL) = {INST, END, NL}
Director(TEST, INST PARAM LOOP) = {INST}
Director(TEST, END) = {END}
Director(LOOP, COMMA PARAM LOOP) = {COMMA}
Director(LOOP, ~) = {NL}
この拡張BNF記法はLL1です。
[error] 0 [warning] 0
CODE ::= { LINE } EOF
LINE ::= [ TEST ] NL
TEST ::= INST PARAM LOOP | END
LOOP ::= { COMMA PARAM }
[warning]
LOOP ::= { COMMA PARAM }
空文字が発生する可能性があるので、空文字を追加します。
CODE ::= { LINE } EOF
LINE ::= [ TEST ] NL
TEST ::= INST PARAM LOOP | END
LOOP ::= { COMMA PARAM } | ~
First(CODE) = {EOF, NL, INST, END}
First(LINE) = {NL, INST, END}
First(TEST) = {INST, END}
First(LOOP) = {COMMA, ~}
Follow(CODE) = {$}
Follow(LINE) = {EOF}
Follow(TEST) = {NL}
Follow(LOOP) = {NL}
Director(CODE, { LINE } EOF) = {NL, INST, END, EOF}
Director(LINE, [ TEST ] NL) = {INST, END, NL}
Director(TEST, INST PARAM LOOP) = {INST}
Director(TEST, END) = {END}
Director(LOOP, { COMMA PARAM }) = {COMMA}
Director(LOOP, ~) = {NL}
この拡張BNF記法はLL1です。
[error] 0 [warning] 1
CODE ::= { LINE } EOF
LINE ::= [ TEST ] NL
TEST ::= INST | END | LOOP
LOOP ::= ( INST | END ) LOOP
CODE ::= { LINE } EOF
LINE ::= [ TEST ] NL
TEST ::= INST | END | LOOP
LOOP ::= ( INST | END ) LOOP
First(CODE) = {EOF, NL, INST, END}
First(LINE) = {NL, INST, END}
First(TEST) = {INST, END}
First(LOOP) = {INST, END}
Follow(CODE) = {$}
Follow(LINE) = {EOF}
Follow(TEST) = {NL}
Follow(LOOP) = {NL}
Director(CODE, { LINE } EOF) = {NL, INST, END, EOF}
Director(LINE, [ TEST ] NL) = {INST, END, NL}
Director(TEST, INST) = {INST}
Director(TEST, END) = {END}
Director(TEST, LOOP) = {INST, END}
Director(LOOP, ( INST | END ) LOOP) = {INST, END}
Director(TEST, INST ) ∩ Director(TEST, INST END ) = {INST}
この拡張BNF記法はLL1ではありません。
[error] 0 [warning] 0
TEST ::= A { [ | ] | ( D | E ) } F
;TEST ::= [A [( B | C ) | ( D | E ) ] F ]
;TEST ::= A { { [B | C] | ( D | E ) } | { [ B | C ] | ( D | E ) } } F
B ::= DATA
D ::= TEST
[warning]
TEST ::= A { [ | ] | ( D | E ) } F
空文字となる"|"があったので削除します。
[warning]
TEST ::= A { [ | ] | ( D | E ) } F
空文字となる括弧があったので削除します。
[warning]
TEST ::= A { [ | ] | ( D | E ) } F
空文字となる"|"があったので削除します。
[error]
TEST ::= A { ( D | E ) } F
括弧が重複しています。
[error] 1 [warning] 3
who3411
MIT(See LISENCE)
Copyright © 2017 who3411 All Rights Reserved.