#前書き
先日、アトリエにてQiitaのWriterが集まる懇親会がありました。
その際に、PepperはBNFを読み込ませて聞き取りをさせると、読み込みに10秒ほどかかるものが、すぐ読み込み終わるとの話を聞きました。
QiitaにはBNFの記事は今日現在で1件しかなかったので、BNFの勉強も兼ねて記事にしようと思います。
#BNFとは?
バッカス・ナウア記法(英: Backus-Naur form)とは、文脈自由文法を定義するのに用いられるメタ言語のことで、一般にBNFやBN記法と略される。現在はこのBNFを拡張したEBNF (Extended BNF) が一般的に使われている。EBNFでは正規表現を用いてより簡単に記述でき、プロトコル規定言語であるASN.1や、XMLの構文定義にも利用されている。
Wikipediaより
https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%83%E3%82%AB%E3%82%B9%E3%83%BB%E3%83%8A%E3%82%A6%E3%82%A2%E8%A8%98%E6%B3%95
詳しくはわからないけど、なんかコンパクトに書けるみたい!!
#PepperとBNF
Pepperに大量の言葉を認識させる方法
http://oyoyo-project.com/blog/?p=282
SpeechReco方式(コンマ区切り方式)で記述した場合はすごく長くなるけど、BNFファイルで記述するとグルーピングして書ける。
#構文
基本的にウィキペディアからの引用です。
##基本
BNF の表記は次のような導出規則の集合である。
<hoge> は <hogehoge> である。
<hoge> ::= <hogehoge>
<hoge> は <abc> または <def> である。
<hoge> ::= <abc> | <def>
<hoge> は <abc><def> である。
<hoge> ::= <abc><def>
##例文を読んでみる
Pepperに大量の言葉を認識させる方法
http://oyoyo-project.com/blog/?p=282
上記にも貼りましたがOYOYO-PROJECTさんの投稿記事の例題を参考にさせてもらいたいと思います。
#BNF+EMV1.1;
!grammar "BNFJapanese";
!start <start>;
!activatable<custom_bnf trig>;
<start>:<custom_bnf trig>;
<custom_bnf trig>:<sts4>|<sts2>|<sts3>;
<sts1>:((にほんむかしばなし)|(やまだくんとしちにんのまじょ)|(ろぐほらいずん)|(にせこい)|(ぎんたま)|);
<sts2>:<sts1>((はきょうそうほう)|(ってきょうそうほう)|(ってほうそうちゅう)|(はほうそうちゅう)|(やってるの));
<sts3>:((じかいの)|(らいしゅうの)|(つぎの))<sts1>;
<sts4>:((いまはなになってる)|(いまやってるあにめは)|(きょうのあにめは));
!grammar "BNFJapanese";
文法、記述言語の定義をしているのでしょう。"BNFJapanese"という言語で書くということ。
!start <start>;
スタートはタグで始まるようです。
!activatable <custom_bnf trig>;
custom_bnfをトリガーとして起動するようです。
custom_bnfはpythonボックスで利用します。
#LCFファイルの呼び出し
self.asr.addContext("LCFファイル入力パス", "custom_bnf")
<start>:<custom_bnf trig>;
<start>を<custom_bnf trig>に置き換えます。
<custom_bnf trig>:<sts4>|<sts2>|<sts3>;
<custom_bnf trig>を<sts4>または<sts2>または<sts3>で置き換えます。
<sts1>:((にほんむかしばなし)|(やまだくんとしちにんのまじょ)|(ろぐほらいずん)|(にせこい)|(ぎんたま));
<sts1>を(にほんむかしばなし)または(やまだくんとしちにんのまじょ)または(ろぐほらいずん)または(にせこい)または(ぎんたま)で置き換えます。
<sts2>:<sts1>((はきょうそうほう)|(ってきょうそうほう)|(ってほうそうちゅう)|(はほうそうちゅう)|(やってるの));
<sts2>を<sts1>(はきょうそうほう)または(ってきょうそうほう)または(ってほうそうちゅう)または(はほうそうちゅう)または(やってるの)に置き換えます。
ex)<sts2>を<sts1>(はきょうそうほう)に置き換えます。
<sts3>:((じかいの)|(らいしゅうの)|(つぎの))<sts1>;
<sts3>を(じかいの)または(らいしゅうの)または(つぎの)<sts1>に置き換えます。
<sts4>:((いまはなになってる)|(いまやってるあにめは)|(きょうのあにめは));
<sts4>を(いまはなになってる)または(いまやってるあにめは)または(きょうのあにめは)に置き換えます。
###HELP!!!
文頭にある
#BNF+EMV1.1;
とは、どのような意味なのでしょうか?
BNFはBNF記法を示しているとして、EMV1.1はどのような意味なのでしょうか?
また、この記述方法だと#以降はコメントアウトになるのか、またはヘッダのようにコンパイラに読み込まれるところになるのでしょうか?
わかる方いたらご教授お願いします。
ぐぐってもさっぱり見つかりませんでした。(英語が読めなかっただけかもしれませんが。)
#使い方
pythonボックスで以下の記述をします。
#BNFファイルをLCFファイルにコンパイル
self.asr = ALProxy("ALSpeechRecognition")
self.asr.compile("BNFファイルの入力パス", "LCFファイルの出力パス", "Japanese")
#LCFファイルの呼び出し
self.asr.addContext("LCFファイル入力パス", "custom_bnf")
詳しくは以下の参考URLを確認して下さい。
ALSpeechRecognition: new methods and event
http://doc.aldebaran.com/2-1/news/2.0/naoqi_api_rn2.0.html?highlight=bnf#alspeechrecognition-new-methods-and-event
#感想
実機テストを行っていないのでNAOでも正しく動くかはわかりませんが、近いうちに検証したいです。