ucl/cmdlang/ast.go

65 lines
1.4 KiB
Go
Raw Normal View History

2024-04-10 10:45:58 +00:00
package cmdlang
import (
2024-04-16 05:39:03 +00:00
"io"
2024-04-10 10:45:58 +00:00
"github.com/alecthomas/participle/v2"
2024-04-12 23:25:16 +00:00
"github.com/alecthomas/participle/v2/lexer"
2024-04-10 10:45:58 +00:00
)
type astLiteral struct {
2024-04-13 11:46:50 +00:00
Str *string `parser:"@String"`
}
type astBlock struct {
Statements []*astStatements `parser:"LC NL? @@ NL? RC"`
2024-04-10 10:45:58 +00:00
}
type astCmdArg struct {
2024-04-10 12:19:11 +00:00
Literal *astLiteral `parser:"@@"`
2024-04-13 11:46:50 +00:00
Ident *string `parser:"| @Ident"`
2024-04-12 23:25:16 +00:00
Var *string `parser:"| DOLLAR @Ident"`
Sub *astPipeline `parser:"| LP @@ RP"`
2024-04-13 11:46:50 +00:00
Block *astBlock `parser:"| @@"`
2024-04-10 10:45:58 +00:00
}
type astCmd struct {
Name string `parser:"@Ident"`
Args []astCmdArg `parser:"@@*"`
}
type astPipeline struct {
First *astCmd `parser:"@@"`
2024-04-12 23:25:16 +00:00
Rest []*astCmd `parser:"( PIPE @@ )*"`
}
2024-04-11 12:05:05 +00:00
type astStatements struct {
First *astPipeline `parser:"@@"`
2024-04-13 11:46:50 +00:00
Rest []*astPipeline `parser:"( NL+ @@ )*"` // TODO: also add support for newlines
2024-04-11 12:05:05 +00:00
}
2024-04-13 11:46:50 +00:00
type astScript struct {
Statements *astStatements `parser:"NL* @@ NL*"`
2024-04-12 23:25:16 +00:00
}
var scanner = lexer.MustStateful(lexer.Rules{
"Root": {
2024-04-13 11:46:50 +00:00
{"Whitespace", `[ \t]+`, nil},
2024-04-12 23:25:16 +00:00
{"String", `"(\\"|[^"])*"`, nil},
{"DOLLAR", `\$`, nil},
{"LP", `\(`, nil},
{"RP", `\)`, nil},
2024-04-13 11:46:50 +00:00
{"LC", `\{`, nil},
{"RC", `\}`, nil},
{"NL", `[;\n][; \n\t]*`, nil},
2024-04-12 23:25:16 +00:00
{"PIPE", `\|`, nil},
2024-04-16 05:39:03 +00:00
{"Ident", `[\w-]+`, nil},
2024-04-12 23:25:16 +00:00
},
})
2024-04-13 11:46:50 +00:00
var parser = participle.MustBuild[astScript](participle.Lexer(scanner),
2024-04-12 23:25:16 +00:00
participle.Elide("Whitespace"))
2024-04-10 10:45:58 +00:00
2024-04-13 11:46:50 +00:00
func parse(r io.Reader) (*astScript, error) {
2024-04-10 10:45:58 +00:00
return parser.Parse("test", r)
}