--- /dev/null
+# 標点の文法(点注会)
+
+grammar Dianzhu
+ rule sentence_seq
+ ( sentence+ )
+ end
+ rule sentence
+ (((phrase ':' quotation) | quotation | phrase_seq )+ fullstop)
+ end
+
+ # 引用はネストしない
+ rule quotation
+ ( '「' phrase_seq '」' )
+ end
+
+ # 説解用
+ rule sentence_part
+ ( sentence_seq? (phrase_seq punctuation)? )
+ end
+# rule phrase_seq
+# ( phrase (punctuation phrase)* )
+# end
+
+ rule phrase_seq
+ ( phrases | phrase )
+ end
+ rule phrases
+ ( phrase punctuation seq:(phrases | phrase) ) {
+ phrase.value + punctuation.value + seq.value
+ }
+ end
+
+# rule phrase
+# ( word+ )
+# end
+ rule phrase
+ ( words | word )
+ end
+ rule words
+ ( word seq:(words | word) ) { word.value + seq.value }
+ end
+
+ rule word
+ ( object | text )
+ end
+ rule object
+ ('[' command ':' text ']') {
+ command.value + "{" + text + "}"
+ }
+ end
+ rule command
+ ( book | chapter | person | fanqie | rime_group )
+ end
+ rule book
+ 'bk' { "\book" }
+ end
+ rule chapter
+ 'ch' { "\chap" }
+ end
+ rule person
+ 'p' { "\pers" }
+ end
+
+ # terminals
+ rule text
+ /[^《》〈〉【】「」。,、:;?!\[\]:a-z]+/u # TODO: 半角を除く \W
+ end
+ rule punctuation
+ /[,、:;]/u
+ end
+ rule fullstop
+ /[。]/u
+ end
+end
--- /dev/null
+require 'rubygems'
+require 'citrus'
+require 'test/unit'
+#require File.join(File.dirname(__FILE__), '..', 'lib', 'tex_objects')
+
+DIANZHU = File.join(File.dirname(__FILE__), '..', 'lib', 'dianzhu')
+
+class DianzhuTest < Test::Unit::TestCase
+ def setup
+ Citrus.load DIANZHU
+ end
+ def assert_parse(string, root)
+ match = DianZhu.parse(string, :root => root)
+ assert(match)
+ assert_equal(string, match)
+ end
+ def assert_parse_error(string, root)
+ assert_raise Citrus::ParseError do
+ Dianzhu.parse(string, :root => root)
+ end
+ end
+ def test_chapter
+ swbook = "[ch:一部]"
+ match = Dianzhu.parse(swbook, :root => :object)
+ assert(match)
+ assert_equal(swbook, match)
+ assert_equal("ch", match.command)
+ assert_equal("\chap{一部}", match.value)
+ end
+ def test_book
+ swbook = "[bk:説文]"
+ match = Dianzhu.parse(swbook, :root => :object)
+ assert(match)
+ assert_equal(swbook, match)
+ assert_equal("bk", match.command)
+ assert_equal("\book{説文}", match.value)
+
+ aswbook = "愛[bk:説文]"
+ match = Dianzhu.parse(aswbook, :root => :phrase)
+ assert(match)
+ assert_equal(aswbook, match)
+ assert_equal("愛\book{説文}", match.value)
+
+ aswbook = "[bk:説文]曰"
+ match = Dianzhu.parse(aswbook, :root => :phrase)
+ assert(match)
+ assert_equal(aswbook, match)
+ assert_equal("\book{説文}曰", match.value)
+
+ swphrase = "[bk:説文],形書也"
+ match = Dianzhu.parse(swphrase, :root => :phrase_seq)
+ assert_equal(swphrase, match)
+ assert_equal("\book{説文},形書也", match.value)
+ end
+end