parser.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package parser
  2. import (
  3. "bufio"
  4. "fmt"
  5. "io"
  6. "strings"
  7. )
  8. type Command struct {
  9. Name string
  10. Arg string
  11. }
  12. func Parse(reader io.Reader) ([]Command, error) {
  13. var commands []Command
  14. scanner := bufio.NewScanner(reader)
  15. multiline := false
  16. var multilineCommand *Command
  17. for scanner.Scan() {
  18. line := scanner.Text()
  19. if multiline {
  20. // If we're in a multiline string and the line is """, end the multiline string.
  21. if strings.TrimSpace(line) == `"""` {
  22. multiline = false
  23. commands = append(commands, *multilineCommand)
  24. } else {
  25. // Otherwise, append the line to the multiline string.
  26. multilineCommand.Arg += "\n" + line
  27. }
  28. continue
  29. }
  30. fields := strings.Fields(line)
  31. if len(fields) == 0 {
  32. continue
  33. }
  34. command := Command{}
  35. switch fields[0] {
  36. case "FROM":
  37. // TODO - support only one of FROM or MODELFILE
  38. command.Name = "image"
  39. command.Arg = fields[1]
  40. case "MODELFILE":
  41. command.Name = "model"
  42. command.Arg = fields[1]
  43. case "PROMPT":
  44. command.Name = "prompt"
  45. if fields[1] == `"""` {
  46. multiline = true
  47. multilineCommand = &command
  48. multilineCommand.Arg = ""
  49. } else {
  50. command.Arg = strings.Join(fields[1:], " ")
  51. }
  52. case "PARAMETER":
  53. command.Name = fields[1]
  54. command.Arg = strings.Join(fields[2:], " ")
  55. default:
  56. continue
  57. }
  58. if !multiline {
  59. commands = append(commands, command)
  60. }
  61. }
  62. if multiline {
  63. return nil, fmt.Errorf("unclosed multiline string")
  64. }
  65. return commands, scanner.Err()
  66. }