Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // == PARSING ==
- // Command { Flag } { Argument } { Delimiter Command { Flag } { Argument } }
- type Parsed struct {
- Pos lexer.Position
- FirstBlock Block ` @@ `
- Blocks []*BlockWithDelim ` @@* `
- }
- type Block struct {
- Command string ` @Command `
- Flags []*ArgFlag ` @@* `
- Arguments []string ` @Argument* `
- }
- type BlockWithDelim struct {
- Delimiter string ` @(";" | "|" | "\n" ) `
- Block Block ` @@ `
- }
- type ArgFlag struct {
- Flag string ` "-" "-"? @Flag `
- Value *string ` ("=" @Argument)? `
- }
- var omegaLexer = lexer.Must(ebnf.New(strings.ReplaceAll(`
- Command = alpha {alpha} .
- Flag = Ident .
- Argument = Ident | String | RawString .
- String = "\"" { "\u0000"…"\uffff"-"\""-"\\" | "\\" "\u0000"…"\uffff" } "\"" .
- RawString = "§" { "\u0000"…"\uffff" - "§" } "§" .
- Ident = (alpha | "_" ) { alpha | digit | "_" } .
- Comment = "#" { "\u0000"…"\uffff" - "\n" } .
- Whitespace = " " | "\t" | "\r" .
- alpha = "a"…"z" | "A"…"Z" .
- digit = "0"…"9" .
- `, "§", "`")))
- var omegaParser = participle.MustBuild(&Parsed{},
- participle.Lexer(omegaLexer),
- participle.Unquote("String", "RawString"),
- participle.Elide("Whitespace", "Comment"))
- // == PROCESSING ==
- type processedCommand struct {
- Command string
- Flags map[string]string
- FlagBools map[string]bool
- Args []string
- Pipe bool
- }
- func parse(input string) ([]*processedCommand, error) {
- parsed := &Parsed{}
- err := omegaParser.ParseString(input, parsed)
- if err != nil {
- return nil, err
- }
- out := []*processedCommand{}
- //Process parsed command
- for c := 0; c < len(parsed.Blocks)+1; c++ {
- pBlock := &processedCommand{}
- block := Block{}
- if c == 0 {
- block = parsed.FirstBlock
- } else {
- block = parsed.Blocks[c].Block
- }
- //Do commands
- pBlock.Command = block.Command
- //Do flags
- pBlock.Flags = make(map[string]string)
- pBlock.FlagBools = make(map[string]bool)
- for _, flag := range block.Flags {
- if flag.Value != nil { //flag with a value
- pBlock.Flags[flag.Flag] = *flag.Value
- } else { //bool flag
- pBlock.FlagBools[flag.Flag] = true
- }
- }
- //Do args
- pBlock.Args = block.Arguments
- //Do pipe
- if c < len(parsed.Blocks) {
- pBlock.Pipe = parsed.Blocks[c+1].Delimiter == "|"
- }
- out = append(out, pBlock)
- }
- return out, nil
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement