一つ前の話なんかを書くには、RFC で使われてる ABNF を読む必要がどうしてもあって。
BNF、EBNF にはそれなりには慣れてるつもりだけど、RFC を読む習慣はそんなにはないので、細かいところが「たぶんそういう意味だろうな」とはわかっても、やっぱしちゃんとわかっとかないと「ワガラン」ところも出てくる。なので ABNF の RFC と WikiPedia を交互に読んでてちょっと混乱した。
というのもね、こう言ってるわけ:
でも「ABNF Definition of ABNF」でこう言ってて:
1 rule = rulename defined-as elements c-nl
2 ; continues if next line starts
3 ; with white space
4
5 rulename = ALPHA *(ALPHA / DIGIT / "-")
6
7 defined-as = *c-wsp ("=" / "=/") *c-wsp
8 ; basic rules definition and
9 ; incremental alternatives
え? え? 自己矛盾してね?
と思ったら違った。すぐ上に書いてあったわ:
2. This syntax uses the rules provided in Appendix B.
1.が完全に説明してるけど、1.を読まなくても 2. を読むだけでもいい。Appendix B (Core Rules) の定義に必要なので、ってことなのね。ABNF のフル定義ではない。なんだよ紛らわしい。
それはそうと、Pygments、EBNF については 2.0 になって書いてくれた人がいたのね。Bryan Davis さん、ですか。うぅ、ついでに ABNF も書いてくれりゃいーのに…。(オリジナル BNF もな。) EBNF は、なので今でも使えて:
1 (* this is comment *)
2 letter = "A" | "B" | "C" | "D" | "E" | "F" | "G"
3 | "H" | "I" | "J" | "K" | "L" | "M" | "N"
4 | "O" | "P" | "Q" | "R" | "S" | "T" | "U"
5 | "V" | "W" | "X" | "Y" | "Z" ;
6 digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
7 symbol = "[" | "]" | "{" | "}" | "(" | ")" | "<" | ">"
8 | "'" | '"' | "=" | "|" | "." | "," | ";" ;
9 character = letter | digit | symbol | "_" ;
10
11 identifier = letter , { letter | digit | "_" } ;
12 terminal = "'" , character , { character } , "'"
13 | '"' , character , { character } , '"' ;
14
15 lhs = identifier ;
16 rhs = identifier
17 | terminal
18 | "[" , rhs , "]"
19 | "{" , rhs , "}"
20 | "(" , rhs , ")"
21 | rhs , "|" , rhs
22 | rhs , "," , rhs ;
23
24 rule = lhs , "=" , rhs , ";" ;
25 grammar = { rule } ;
こういう技術説明に不可欠なものは、やっぱし Syntax Highlighting があると断然説明しやすい。先天的に脳味噌フル活用して読む類のもんだから、読みにくさだけで疲れたくはない。
なんか ABNF lexer も欲しくなっちゃった。難しくはない、と思う。(ついでにいえば EBNF lexer は少し気に入らない。r'([a-zA-Z][\w \-]*)'
全部を「Keyword」トークンにしちゃうのはちょいと乱暴だ。)
追記:
ABNF の lexer、書いた。