Advertisement
Guest User

Untitled

a guest
Dec 4th, 2019
363
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 2.35 KB | None | 0 0
  1. // == PARSING ==
  2.  
  3. // Command { Flag } { Argument } { Delimiter Command { Flag } { Argument } }
  4.  
  5. type Parsed struct {
  6.     Pos lexer.Position
  7.  
  8.     FirstBlock Block             ` @@ `
  9.     Blocks     []*BlockWithDelim ` @@* `
  10. }
  11.  
  12. type Block struct {
  13.     Command   string     ` @Command `
  14.     Flags     []*ArgFlag ` @@* `
  15.     Arguments []string   ` @Argument* `
  16. }
  17.  
  18. type BlockWithDelim struct {
  19.     Delimiter string ` @(";" | "|" | "\n" ) `
  20.     Block     Block  ` @@ `
  21. }
  22.  
  23. type ArgFlag struct {
  24.     Flag  string  ` "-" "-"? @Flag `
  25.     Value *string ` ("=" @Argument)? `
  26. }
  27.  
  28. var omegaLexer = lexer.Must(ebnf.New(strings.ReplaceAll(`
  29.     Command = alpha {alpha} .
  30.     Flag = Ident .
  31.     Argument = Ident | String | RawString .
  32.     String = "\"" { "\u0000"…"\uffff"-"\""-"\\" | "\\" "\u0000"…"\uffff" } "\"" .
  33.     RawString = "§" { "\u0000"…"\uffff" - "§" } "§" .
  34.     Ident = (alpha | "_" ) { alpha | digit | "_" } .
  35.  
  36.     Comment = "#" { "\u0000"…"\uffff" - "\n" } .
  37.     Whitespace = " " | "\t" | "\r" .
  38.  
  39.     alpha = "a"…"z" | "A"…"Z" .
  40.     digit = "0"…"9" .
  41. `, "§", "`")))
  42.  
  43. var omegaParser = participle.MustBuild(&Parsed{},
  44.     participle.Lexer(omegaLexer),
  45.     participle.Unquote("String", "RawString"),
  46.     participle.Elide("Whitespace", "Comment"))
  47.  
  48. // == PROCESSING ==
  49.  
  50. type processedCommand struct {
  51.     Command   string
  52.     Flags     map[string]string
  53.     FlagBools map[string]bool
  54.     Args      []string
  55.     Pipe      bool
  56. }
  57.  
  58. func parse(input string) ([]*processedCommand, error) {
  59.     parsed := &Parsed{}
  60.     err := omegaParser.ParseString(input, parsed)
  61.     if err != nil {
  62.         return nil, err
  63.     }
  64.  
  65.     out := []*processedCommand{}
  66.  
  67.     //Process parsed command
  68.     for c := 0; c < len(parsed.Blocks)+1; c++ {
  69.         pBlock := &processedCommand{}
  70.         block := Block{}
  71.         if c == 0 {
  72.             block = parsed.FirstBlock
  73.         } else {
  74.             block = parsed.Blocks[c].Block
  75.         }
  76.  
  77.         //Do commands
  78.         pBlock.Command = block.Command
  79.  
  80.         //Do flags
  81.         pBlock.Flags = make(map[string]string)
  82.         pBlock.FlagBools = make(map[string]bool)
  83.         for _, flag := range block.Flags {
  84.             if flag.Value != nil { //flag with a value
  85.                 pBlock.Flags[flag.Flag] = *flag.Value
  86.             } else { //bool flag
  87.                 pBlock.FlagBools[flag.Flag] = true
  88.             }
  89.         }
  90.  
  91.         //Do args
  92.         pBlock.Args = block.Arguments
  93.  
  94.         //Do pipe
  95.         if c < len(parsed.Blocks) {
  96.             pBlock.Pipe = parsed.Blocks[c+1].Delimiter == "|"
  97.         }
  98.  
  99.         out = append(out, pBlock)
  100.     }
  101.  
  102.     return out, nil
  103. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement