parser.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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. var foundModel bool
  15. scanner := bufio.NewScanner(reader)
  16. multiline := false
  17. var multilineCommand *Command
  18. for scanner.Scan() {
  19. line := scanner.Text()
  20. if multiline {
  21. // If we're in a multiline string and the line is """, end the multiline string.
  22. if strings.TrimSpace(line) == `"""` {
  23. multiline = false
  24. commands = append(commands, *multilineCommand)
  25. } else {
  26. // Otherwise, append the line to the multiline string.
  27. multilineCommand.Arg += "\n" + line
  28. }
  29. continue
  30. }
  31. fields := strings.Fields(line)
  32. if len(fields) == 0 {
  33. continue
  34. }
  35. command := Command{}
  36. switch strings.ToUpper(fields[0]) {
  37. case "FROM":
  38. command.Name = "model"
  39. command.Arg = fields[1]
  40. if command.Arg == "" {
  41. return nil, fmt.Errorf("no model specified in FROM line")
  42. }
  43. foundModel = true
  44. case "PROMPT":
  45. command.Name = "prompt"
  46. if fields[1] == `"""` {
  47. multiline = true
  48. multilineCommand = &command
  49. multilineCommand.Arg = ""
  50. } else {
  51. command.Arg = strings.Join(fields[1:], " ")
  52. }
  53. case "PARAMETER":
  54. command.Name = fields[1]
  55. command.Arg = strings.Join(fields[2:], " ")
  56. default:
  57. continue
  58. }
  59. if !multiline {
  60. commands = append(commands, command)
  61. }
  62. }
  63. if !foundModel {
  64. return nil, fmt.Errorf("no FROM line for the model was specified")
  65. }
  66. if multiline {
  67. return nil, fmt.Errorf("unclosed multiline string")
  68. }
  69. return commands, scanner.Err()
  70. }