parser-range.scm 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. (define-module (semver parser-range)
  2. #:use-module (srfi srfi-1)
  3. #:use-module (ice-9 match)
  4. #:use-module (ice-9 peg)
  5. #:use-module (semver structs)
  6. #:use-module (semver matcher)
  7. #:export (parse-semver-range))
  8. (define-peg-string-patterns
  9. "range-set <- range (logical-or range) *
  10. logical-or <-- (whitespace)* '||' (whitespace)*
  11. qualifier <-- ('-' pre)? ('+' range)?
  12. pre <- parts
  13. range <- parts
  14. parts <- part ('.' part)*
  15. part <- nr / [-0-9A-Za-z]+
  16. nr <- [1-9] ([0-9])* / [0]
  17. xr <- 'x' / 'X' / '*' / nr
  18. lt <-- '<'
  19. lte <-- '<' '='
  20. gt <-- '>'
  21. gte <-- '>' '='
  22. eq <-- '='
  23. partial <-- xr ('.' xr ('.' xr qualifier ? )? )?
  24. hyphen <-- partial (whitespace)+ '-' (whitespace)+ partial
  25. primitive <- ( gte /gt / lte /lt / eq) (whitespace)* partial
  26. tilde <-- '~' (whitespace)* partial
  27. caret <-- '^' (whitespace)* partial
  28. simple <- primitive / partial / tilde / caret
  29. range <- hyphen / (simple (whitespace+ simple)*)
  30. whitespace < ' ' / '\t'")
  31. (define (parse-semver-range expr)
  32. "Parse EXPR for a valid (prefix) semantic version range
  33. string. Return #f when no such string is recognised."
  34. (define (split str)
  35. (string-split str #\.))
  36. (define (semver-range-from-str str)
  37. (apply semver-range-partial (split str)))
  38. (define (matcher tree)
  39. (match tree
  40. ((left (('logical-or _) right))
  41. (semver-range-or (matcher left)
  42. (matcher right)))
  43. (('partial v)
  44. (semver-range-from-str v))
  45. ((('eq _) ('partial v))
  46. (semver-range-from-str v))
  47. ((('lt _) ('partial v))
  48. (semver-range-lt (semver-range-from-str v)))
  49. ((('gt _) ('partial v))
  50. (semver-range-gt (semver-range-from-str v)))
  51. ((('lte _) ('partial v))
  52. (semver-range-lte (semver-range-from-str v)))
  53. ((('gte _) ('partial v))
  54. (semver-range-gte (semver-range-from-str v)))
  55. (('tilde _ ('partial v))
  56. (semver-range-tilde (semver-range-from-str v)))
  57. (('caret _ ('partial v))
  58. (semver-range-caret (semver-range-from-str v)))
  59. (('hyphen ('partial v-left) _ ('partial v-right))
  60. (semver-range-hyphen (semver-range-from-str v-left)
  61. (semver-range-from-str v-right)))
  62. ((left ((('logical-or _) all-right) ...))
  63. (fold semver-range-or (matcher left)
  64. (map matcher all-right)))
  65. ((left right)
  66. (semver-range-and (matcher left)
  67. (matcher right)))
  68. (_
  69. (error "We could not parse that quite right."))))
  70. (let ((parsed (peg:tree (match-pattern range-set expr))))
  71. (matcher parsed)))