使ってみる
使い方は PEG に慣れていればなんの抵抗もないはずですが、
私のように正規表現しか書いたことのない人間には馴染みの薄い物です。
では先日使用した json をそのまま流用して試してみます。
使用した json は json.org の JSON Example の一番上のやつです。
http://json.org/example.html
この json を example.json として保存し、使用しています。
"SortAs": "SGML",
json からkey, value (この場合は SortAs:SGML )を得たい場合
PEG ではこのように書くことができます
'"' {( \w )+} '":' \s+ '"' {( \w )+} '"' ','?
"Abbrev": "ISO 8879:1986",
この場合は
'"' {( \w )+} '":' \s+ '"' {( \w / \s / ':' )+} '"' ','?
となります。
これらの規則は非終端記号として定義できます。
grammer <- '"' {( \w )+} '":' \s+ '"' {( \w / \s / ':' )+} '"' ','?
key, value 部分をまとめて以下のような記述にもできます。
grammer <- '"' cap '":' \s+ '"' cap '"' ','?
cap <- {( \w / \s / ':' )+}
最後に、json 全体をパースしてみます
rule <- '{' \s+
'"glossary":' \s+ '{' \s+
title
'"GlossDiv":' \s+ '{' \s+
title
'"GlossList":' \s+ '{' \s+
'"GlossEntry":' \s+ '{' \s+
(glossDef / pair)*
glossDef <- '"GlossDef":' \s+ '{' \s+ pair '},' \s+
pair <- '"' cap '":' \s+ '"' cap '"' ','? \s+
title <- '"title":' \s+ '"' cap '",' \s+
cap <- {( \w / \s / [.,-:;] )+}
このままだと nim ではなく PEG の話になるので申し訳程度にコードと結果を載せておきます
ちなみに今回の json でしか機能せず汎用性は全くありませんので...
import pegs
const peg = """
rule <- '{' \s+
'"glossary":' \s+ '{' \s+
title
'"GlossDiv":' \s+ '{' \s+
title
'"GlossList":' \s+ '{' \s+
'"GlossEntry":' \s+ '{' \s+
(glossDef / pair)*
glossDef <- '"GlossDef":' \s+ '{' \s+ pair '},' \s+
pair <- '"' cap '":' \s+ '"' cap '"' ','? \s+
title <- '"title":' \s+ '"' cap '",' \s+
cap <- {( \w / \s / [.,-:;] )+}
"""
let str = "example.json".readFile()
if str =~ peg(peg):
for i in 0..(matches.len - 1):
if i < 2:
echo "title: ", matches[i]
else:
if matches[i] != nil:
if i mod 2 == 0:
echo "key: ", matches[i]
else:
echo "value: ", matches[i]
この出力は以下の通りです。
title: example glossary
title: S
key: ID
value: SGML
key: SortAs
value: SGML
key: GlossTerm
value: Standard Generalized Markup Language
key: Acronym
value: SGML
key: Abbrev
value: ISO 8879:1986
key: para
value: A meta-markup language, used to create markup languages such as DocBook.
key: GlossSee
value: markup