2017年9月26日火曜日

Bake tiny calc app at antlr3 and Clang with emscripten

ゲームスクリプトを設計しようかと考えた。
文字で書かれた文章を構造化して、書かれた事を実行する。
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




0 件のコメント:

コメントを投稿

ServiceWorler メモ

Service Worker の オフライン機能を利用したいので、 あれこれ試してみた。 Memo PWA (0) Memo PWA (1) ServiceWorker for offlineapp Memo PWA (2) Dart PWA Package