ゲームスクリプトを設計しようかと考えた。
文字で書かれた文章を構造化して、書かれた事を実行する。
ANTLR を 使う事にした。
Emscripteで利用するまでについて、解説します。
結論から
ANTLR3 (http://www.antlr3.org/)を利用します。ANTLR4は、C言語がなさげ、CPPはあります!!
ANTLR3 で 生成した Parser と Lexer は、 emscriptenようにビルドしましょう。
少しだけ変更します。以下の通り
電卓を作りました。参考までにどうぞ
コンパイラーコンパイラー
文字で書かれた文章を構造化するのに、Lexer と Parser を作るのがトレンドです。
Lexerで単語を分割する。Parserで分割した単語を木構造化するといった感じです。
こう書くと難しそうですが、いたって簡単です。
文章を構造化するとは、プログラマー的には、文章を関数化するという事です。
これを、念頭に読んでください
「xxx は yyy が zzz です。」を構造化してみましょう。
関数で木構造を表現する
void sentence() {
xxx();
printf("は");
yyy();
printf("が");
zzz();
printf("です。");
}
void xxx() {
printf("私");
}
void yyy() {
printf("ポテチ");
}
void zzz() {
printf("すき");
}
こんな感じで出かけます。 xxx() yyy() zzz()を、自分好みに書き換えれば、
構造化の完成です。
今回の場合だと、「私はポテチが好きです」と表示されるはずです。
関数で構造解析木をつくる
xxx() yyy() zzz() の部分に何が入るかを、解析するのが、Parserです。
void sentence(char *src) {
src = xxx(src+1);
if(src[0] !="は") {
return; // failed to parse
}
src = yyy(src+1);
if(src[0] == "が") {
return; // failed to parse
}
src = zzz(src+1);
if(src[0] != "で" || src[0] != "す") {
return; // failed to parse
}
}
char* xxx(char *src) {
char data[100] = 0;
for(int i=0;;i++) {
if(src[i] == 'は') {
return src+i;
}else {
data[i] = src[i];
}
}
}
char* yyy(char *src) {
char data[100] = 0;
for(int i=0;;i++) {
if(src[i] == 'が') {
return src+i;
}else {
data[i] = src[i];
}
}
}
char* zzz(char *src) {
char data[100] = 0;
for(int i=0;;i++) {
if(src[i] == 'で') {
return src+i;
}else {
data[i] = src[i];
}
}
}
こんな感じです。書くのが大変ですね。
コンパイラーコンパイラーが、かわりにやってくれる
この、大変な作業を、BNF形式で記述すれば自動で生成してくれるのが、
コンパイラーコンパイラーと言われるものです。
今回は、ANTLR(http://www.antlr.org/)を利用しました。
ANTLRについて
C言語は、ANTLR3をつかう
antlr4だと、C++ようはあるのですが、C言語用がありません。
Emscriptenようには、ビルドする
このコードを、自分でビルドします。少しだけ変更が必要でした、
ninja build できるようにしたものを、以下に起きました。
Java版は生成されるのに、C言語版はWarningがでる
```
warning(24): template error: context [/outputFile /parser] 1:1 could not pass through undefined attribute filterMode
warning(24): template error: context [/outputFile /parser /genericParser /_sub45 /ruleAttributeScopeFuncMacro] 1:4 no such property or can't access: null.attributes
warning(24): template error: context [/outputFile /parser /genericParser /_sub45 /ruleAttributeScopeFuncMacro] 1:4 no such property or can't access: null.attributes
```
これは、でても問題ないそうです..
出力するParserの言語のしていは、グラマーファイルに書く
こんな感じ
PS
電卓のサンプルを起きました。
参考までにどうぞ。
REF BOOK
https://pragprog.com/book/tpdsl/language-implementation-patterns
https://pragprog.com/titles/tpantlr/index.html
https://contrapunctus.net/blog/2012/antlr-c
http://www.antlr3.org/
http://www.antlr.org/
おわり
------
試したコード
https://github.com/kyorohiro/libantlr3c_emscripten
https://github.com/kyorohiro/sdl2_doc
This codes can build for windows and mac and html5 on windows and mac
作成中のライブラリー
https://github.com/kyorohiro/cgame
ことはじめ
https://kyorohiro.blogspot.jp/2017/09/which-use-sdl1-or-sdl2-at-emscripten.html
https://pragprog.com/titles/tpantlr/index.html
blog
http://kripken.github.io/emscripten-site/https://contrapunctus.net/blog/2012/antlr-c
http://www.antlr3.org/
http://www.antlr.org/
おわり
------
試したコード
https://github.com/kyorohiro/libantlr3c_emscripten
https://github.com/kyorohiro/sdl2_doc
This codes can build for windows and mac and html5 on windows and mac
作成中のライブラリー
https://github.com/kyorohiro/cgame
ことはじめ
https://kyorohiro.blogspot.jp/2017/09/which-use-sdl1-or-sdl2-at-emscripten.html