[Go]
PEGをやりたいんや
- EDIT: 2021/08/20
- 構文解析やるならgoyaccとかbison/flexとかでもよかった
環境構築
Go を見てや
- Emacs準備
- .emacsに追記
(add-to-list 'auto-mode-alist '("\\.peg$" . peg-mode))
参考サイト
PEGしてみる
まずライブラリをGoでとってくるぞgo getでソースをとってビルド、-dでソースを取得するのみ
$ go get github.com/pointlander/peg go get github.com/pointlander/peg can't load package: package github.com/pointlander/peg: no buildable Go source files in /home/hiroyuki/.go/src/github.com/pointlander/peg
は?たぶん、Linux版はこれをやらないとダメ(クソ)
$ mkdir -p $GOPATH/src/github.com/pointlander/peg
違いました、先に空のディレクトリがあるとエラーが出るようです。消しときましょう。
$ rm -rf $GOPATH/src/github.com/pointlander/
ようやくpegが入るので、以下を実行
$ peg scan.peg
今考えるとgo getではなくgo installのほうがよかったか
PEGの文法に関する資料
- 読み込みたいアセンブラ例文
# nimonic + parameters DB 0xeb, 0x4e, 0x90, 0x48, 0x45, 0x4c, 0x4c, 0x4f # nimonic + operand + , + operand MOV AL,0x13
Introduction to PEG より Parsing Expression
- N : 規則(非終端記号)の参照
- "a" : 文字列a
- ε : 空文字列
- . : 任意の一文字
- [...] : 文字クラス
- e1 e2 : e1とe2の並び
- e1 / e2 : e1を試し、失敗したらe2を試す
- e1 / e2 ≠ e2 / e1
- e? : 0回または1回の繰り返し
- e* : 0回以上の繰り返し
- e+ : 1回以上の繰り返し
- &e : And-predicate
- eがマッチしたら成功。入力を消費しない
- !e : Not-predicate
- eがマッチしなければ成功。入力を消費しない シンプル!
Qiita - PEGを書きやすくする拡張構文の調査(字句ルール編)
scan.pegを考察
// // root要素は "expression + EOT" または "expression + ? + EOT" // root <- expression EOT / expression <.+> {p.s.Err(begin)} EOT / <.+> {p.s.Err(begin)} EOT // // EOT要素は "literal"の連続 // EOT <- !. expression <- literal literal* // // literal要素の定義 // literal <- <&'0' [0-9]+> { // p,begin,end,text を使用する場合はruleを<…>で囲む。 // '0'で始まる数字列 fmt.Printf("line %d(%d) KIND:ZeroNUMBER \"%s\"\n", p.s.line, begin - p.s.lineHead, text) } / <[0-9]+> { // 数字列 fmt.Printf("line %d(%d) KIND:NUMBER \"%s\"\n", p.s.line, begin - p.s.lineHead, text) } / <[[A-Z]]+> { // 大小英字列 fmt.Printf("line %d(%d) KIND:IDENT \"%s\"\n", p.s.line, begin - p.s.lineHead, text) } / ' '+ { } / <'\n'> { // 改行時処理 p.s.line++; p.s.lineHead = begin + 1 } / <[^0-9a-zA-Z \n]+> { // その他文字 fmt.Printf("line %d(%d) KIND:OTHER \"%s\"\n", p.s.line, begin - p.s.lineHead, text) }