parser_impl.km 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. type ValueParserType Parser[Value,Error];
  2. function Keyword:
  3. &(String) => Parser[unit,Error]
  4. &(keyword) => { consume (keyword, { Error { "expect '?'" keyword } }) };
  5. function Chars:
  6. & { accept: List[Char] } => Parser[Char,Error]
  7. & { accept } =>
  8. let err := { Error 'unexpected character or EOF' },
  9. { choose (accept map &(char) =>
  10. ({ consume ([char].{String}, err) } map &(_) => char)) };
  11. const Blank: Parser[unit,Error] :=
  12. { Chars { accept: { List (' '..\t..\r..\n) } } }
  13. . { map &(_) => () };
  14. function WrappedList:[T]
  15. & { item: Parser[T,Error],
  16. sep: Parser[unit,Error],
  17. prefix: Parser[unit,Error],
  18. suffix: Parser[unit,Error] }
  19. => Parser[List[T],Error]
  20. & { item, sep, prefix, suffix } =>
  21. let item := (item with-ignored Blank),
  22. let sep := (sep with-ignored Blank),
  23. \ apply prefix,
  24. \ list := apply { repeat { item, sep } },
  25. \ apply suffix,
  26. { output list };
  27. function ValueParser: &() => ValueParserType
  28. &() =>
  29. { choose [
  30. { throw { Error 'parser stuck' } },
  31. { make-lazy ObjectParser }, { make-lazy ArrayParser },
  32. StringParser, NumberParser, BoolParser, NullParser
  33. ] };
  34. function ObjectParser: &() => ValueParserType
  35. &() =>
  36. let entry :=
  37. \ key := apply StringParser*,
  38. \ apply ({ Keyword ':' } with-ignored Blank),
  39. \ value := apply { ValueParser () },
  40. { output (key,value) },
  41. let entries := { WrappedList {
  42. item: entry,
  43. sep: { Keyword ',' },
  44. prefix: { Keyword '{' },
  45. suffix: { Keyword '}' }
  46. } },
  47. (entries map &(entries) => { Object { Map entries } });
  48. function ArrayParser: &() => ValueParserType
  49. &() =>
  50. let items := { WrappedList {
  51. item: { ValueParser () },
  52. sep: { Keyword ',' },
  53. prefix: { Keyword '[' },
  54. suffix: { Keyword ']' }
  55. } },
  56. (items map &(items) => { Array items });
  57. const NullParser: ValueParserType :=
  58. { Keyword 'null' }
  59. . { map &() => Null };
  60. const TrueParser: ValueParserType :=
  61. { Keyword 'true' }
  62. . { map &() => { Bool Yes } };
  63. const FalseParser: ValueParserType :=
  64. { Keyword 'false' }
  65. . { map &() => { Bool No } };
  66. const BoolParser: ValueParserType :=
  67. { choose [TrueParser, FalseParser] };
  68. const NumberParser: ValueParserType :=
  69. \ chars := apply { repeat { Chars { accept: { List '0123456789.Ee+-' } } } },
  70. switch { parse-float chars.{String} }:
  71. case Some x:
  72. { output { Number x } },
  73. case None:
  74. { throw { Error 'invalid number' } },
  75. end;
  76. const StringParser: ValueParserType :=
  77. (StringParser* map &(string) => { |Value| string });
  78. const StringParser*: Parser[self::String,Error] :=
  79. let err := { Error 'invalid string' },
  80. \ apply { consume ('"', err) },
  81. &(input) =>
  82. let proceed:
  83. &(Seq[Char], String) => Maybe[(Seq[Char],String)] :=
  84. &(chars, input) rec(proceed) =>
  85. \ (this, input) := get { shift input },
  86. \ (prev, _) := get { shift chars },
  87. let chars := (this cons chars),
  88. if ((this = `"`) and (prev != `\`)):
  89. { Some (chars, input) },
  90. else:
  91. { proceed (chars, input) },
  92. switch { proceed ((`"` cons Nil), input) }:
  93. case Some (chars, input):
  94. let raw := chars.{List}.{reverse}.{String},
  95. switch { unquote raw }:
  96. case Some content:
  97. let value := { |self::String| content },
  98. { Success (value, input) },
  99. case None:
  100. { Failure (err, input) },
  101. end,
  102. case None:
  103. { Failure (err, input) },
  104. end;