58 lines
1.5 KiB
Go
58 lines
1.5 KiB
Go
package tcl
|
|
|
|
import (
|
|
"log"
|
|
"os"
|
|
|
|
"github.com/davecgh/go-spew/spew"
|
|
. "github.com/oec/goparsify"
|
|
)
|
|
|
|
// Tcl parser, using combinators
|
|
// Based on the grammer in:
|
|
// https://wiki.tcl-lang.org/page/BNF+for+Tcl
|
|
|
|
var (
|
|
word Parser
|
|
commands Parser
|
|
script Parser
|
|
)
|
|
|
|
var (
|
|
comment = NewParser("comment", Merge(NoAutoWS(Seq("#", NotChars("\r\n"))))).Map(found("comment"))
|
|
wordExp = NewParser("{*}word", NoAutoWS(Seq("{*}", &word))).Map(found("wordExp"))
|
|
wordSub = NewParser("[*]word", NoAutoWS(Seq("[*]", &word))).Map(found("wordSub"))
|
|
wordBrc = NewParser("{word}", Seq("{", &word, "}")).Map(found("wordBrc"))
|
|
wordQtd = NewParser(`"word"`, StringLit(`"`)).Map(found("wordQtd"))
|
|
wordSmp = NewParser("simple", NotChars("{}[]*")).Map(found("simple"))
|
|
command = NewParser("command", Many(&word)).Map(found("command")).Map(found("command"))
|
|
)
|
|
|
|
func init() {
|
|
word = NewParser("word", Any(&wordSmp, &wordQtd, &wordBrc, &wordSub, &wordExp)).Map(found("word"))
|
|
commands = NewParser("commands", Any(&command, Maybe(Chars(";"))))
|
|
script = NewParser("script", Many(Any(&comment, &commands)))
|
|
}
|
|
|
|
func Parse(input string) (data interface{}, e error) {
|
|
data, e = Run(&script, input, ASCIIWhitespace)
|
|
return
|
|
}
|
|
|
|
func ParseDebug(input string) (data interface{}, e error) {
|
|
EnableLogging(os.Stdout)
|
|
data, e = Run(&script, input, ASCIIWhitespace)
|
|
return
|
|
}
|
|
|
|
func found(typ string) func(*Result) {
|
|
return func(r *Result) {
|
|
log.Println("found a", typ)
|
|
spew.Dump(r)
|
|
|
|
}
|
|
}
|
|
func dump(r *Result) {
|
|
spew.Dump(r)
|
|
}
|