Goでpegを使って構文解析をしてみた。
最初に peg コマンドをインストールするので、以下のコマンドを実行する。
make setup
その後は以下のコマンドでビルドする。
make
./configfile
⟩ ./configifle
value = {0 31 }
value = {0 42 }
value = {1 0 hello world}
module configfile | |
go 1.17 |
package main | |
type Parser Peg { | |
ParserFunc | |
} | |
root <- (colors / text)* | |
colors <- | |
prefix color (delimiter color)* suffix | |
prefix <- | |
'\e' '[' | |
color <- | |
<([349] / '10') [0-7]> { p.pushColor(text) } | |
text <- <[^\e]+> { p.pushText(text) } | |
suffix <- 'm' | |
delimiter <- ';' |
package main | |
import ( | |
"fmt" | |
"os" | |
"strconv" | |
) | |
type ParserFunc struct { | |
data []Data | |
currentKey string | |
} | |
type Data struct { | |
Type DataType | |
Color Color | |
Text string | |
} | |
type DataType int | |
type Color int | |
const ( | |
typeColor DataType = iota | |
typeText | |
colorForegroundBlack Color = 30 + iota | |
colorForegroundRed | |
colorForegroundGreen | |
colorForegroundBrown | |
colorForegroundBlue | |
colorForegroundMagenta | |
colorForegroundCyan | |
colorForegroundWhite | |
colorBackgroundBlack Color = 40 + iota | |
colorBackgroundRed | |
colorBackgroundGreen | |
colorBackgroundBrown | |
colorBackgroundBlue | |
colorBackgroundMagenta | |
colorBackgroundCyan | |
colorBackgroundWhite | |
// 90系、100系は省略 | |
) | |
func (p *ParserFunc) pushColor(text string) { | |
n, _ := strconv.Atoi(text) | |
c := Color(n) | |
d := Data{ | |
Type: typeColor, | |
Color: c, | |
} | |
p.data = append(p.data, d) | |
} | |
func (p *ParserFunc) pushText(text string) { | |
d := Data{ | |
Type: typeText, | |
Text: text, | |
} | |
p.data = append(p.data, d) | |
} | |
func main() { | |
b, err := os.ReadFile("sample.txt") | |
if err != nil { | |
panic(err) | |
} | |
pf := ParserFunc{ | |
data: make([]Data, 0), | |
} | |
p := &Parser{ | |
Buffer: string(b), | |
ParserFunc: pf, | |
} | |
if err := p.Init(); err != nil { | |
panic(err) | |
} | |
if err := p.Parse(); err != nil { | |
panic(err) | |
} | |
p.Execute() | |
for _, v := range p.ParserFunc.data { | |
fmt.Printf("value = %v\n", v) | |
} | |
} |
configfile: *.go grammer.peg.go | |
go build | |
grammer.peg.go: grammer.peg | |
peg grammer.peg | |
.PHONY: setup | |
setup: ## 開発時に使うツールをインストールする | |
go install github.com/pointlander/peg@latest |
[31;42mhello world |