Tech Tips

  1. プログラミング
  2. 669 view

[Parser][PEG]PEG.jsで遊んでみる

最近、文脈自由文法よりも扱える範囲が広いかもしれないと言われている
分析的形式文法(PEG)に興味があって、リッチなコンフィグファイル用言語を作成するのに使用している。 PEG.jsというPEG用のパーサを生成してくれるjsがgithub上に公開されていて、
これを使っている。
http://pegjs.majda.cz/ 今作っている言語の文法は以下のように定義していて
start
= tree

tree
= stat:statement? { return stat; }

statement
= stat:if_statement { return stat.toString(); }
/ stat:proc_statement { return stat.toString(); }

if_statement
= fac:if_factor 'Y' edge branch1:proc_statement '\n'
'N' '\n' edge branch2:statement
{ return branch2.toString().match(/if/) ?
"if (" + fac + ")\n\t" + branch1 + '\nelse ' + branch2
: 'if (' + fac + ')\n\t' + branch1 + '\nelse\n\t' + branch2;}

proc_statement
= fac1:proc_factor [-|]+ fac2:proc_statement { return fac1 + '.then(' + fac2.slice(0,fac2.length-1) + ');'; }
/ factor:proc_factor { return factor + ';'; }

proc_factor
= '[' procexp:expression ']' { return procexp; }
if_factor
= '<' ifexp:expression '>' { return ifexp; }

expression
= elem:element ' ' cdr:arguments { return elem.toString() + '(' +cdr + ')'; }
/ elem:element { return elem.toString(); }

arguments
= elem:element ',' arg:arguments { return elem.toString() + ',' + arg; }
/ elem:element { return elem.toString(); }

element
= characters:[a-zA-Z0-9-_."]+ { return characters.join('') }

edge
= symbols:[-|\n]+ { return symbols.join('') }
例えば次のような文章を解析できる。
<hasTwitterAccount id>Y---[getTweet id]---[outputTweets]
N
|
|
<hasYoutubeAccount id>Y-----[youtube_search keyword,30]
N
|
|
|
|
|
[alert "nothing"]
github上のリポジトリはこれ

プログラミングの最近記事

  1. Google Calendar API で自分のカレンダーの予定を取得する方法

  2. LeetCode の問題リストページで Like/Dislike 数を表示するだけの雑な …

  3. AWS Amplify Console + Nuxt.js で特定のパス以下にデプロイする…

  4. LeetCode で解いた問題数が 300 を超えました

  5. ECDSA の SSL 自己証明書の作成方法

関連記事

PAGE TOP