トップ 差分 一覧 ソース 検索 ヘルプ RSS ログイン

Go言語でPEG

[Go]

PEGをやりたいんや

環境構築

Go を見てや

  • .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

  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)
        }
お名前: コメント: