line_parsers.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package parser
  2. import (
  3. "encoding/json"
  4. "strconv"
  5. "strings"
  6. )
  7. // ignore the current argument. This will still leave a command parsed, but
  8. // will not incorporate the arguments into the ast.
  9. func parseIgnore(rest string) (*Node, error) {
  10. return blankNode(), nil
  11. }
  12. func parseSubCommand(rest string) (*Node, error) {
  13. _, child, err := parseLine(rest)
  14. if err != nil {
  15. return nil, err
  16. }
  17. return &Node{Children: []*Node{child}}, nil
  18. }
  19. // parse environment like statements. Note that this does *not* handle
  20. // variable interpolation, which will be handled in the evaluator.
  21. func parseEnv(rest string) (*Node, error) {
  22. node := blankNode()
  23. rootnode := node
  24. strs := TOKEN_WHITESPACE.Split(rest, 2)
  25. node.Value = QuoteString(strs[0])
  26. node.Next = blankNode()
  27. node.Next.Value = QuoteString(strs[1])
  28. return rootnode, nil
  29. return node, nil
  30. }
  31. // parses a whitespace-delimited set of arguments. The result is effectively a
  32. // linked list of string arguments.
  33. func parseStringsWhitespaceDelimited(rest string) (*Node, error) {
  34. node := blankNode()
  35. rootnode := node
  36. for _, str := range TOKEN_WHITESPACE.Split(rest, -1) { // use regexp
  37. node.Value = QuoteString(str)
  38. node.Next = blankNode()
  39. node = node.Next
  40. }
  41. return rootnode, nil
  42. }
  43. // parsestring just wraps the string in quotes and returns a working node.
  44. func parseString(rest string) (*Node, error) {
  45. return &Node{QuoteString(rest), nil, nil}, nil
  46. }
  47. // parseJSON converts JSON arrays to an AST.
  48. func parseJSON(rest string) (*Node, error) {
  49. var (
  50. myJson []interface{}
  51. next = blankNode()
  52. orignext = next
  53. )
  54. if err := json.Unmarshal([]byte(rest), &myJson); err != nil {
  55. return nil, err
  56. }
  57. for _, str := range myJson {
  58. switch str.(type) {
  59. case float64:
  60. str = strconv.FormatFloat(str.(float64), 'G', -1, 64)
  61. }
  62. next.Value = QuoteString(str.(string))
  63. next.Next = blankNode()
  64. next = next.Next
  65. }
  66. return orignext, nil
  67. }
  68. // parseMaybeJSON determines if the argument appears to be a JSON array. If
  69. // so, passes to parseJSON; if not, quotes the result and returns a single
  70. // node.
  71. func parseMaybeJSON(rest string) (*Node, error) {
  72. rest = strings.TrimSpace(rest)
  73. if strings.HasPrefix(rest, "[") {
  74. node, err := parseJSON(rest)
  75. if err == nil {
  76. return node, nil
  77. }
  78. }
  79. node := blankNode()
  80. node.Value = QuoteString(rest)
  81. return node, nil
  82. }