PageRenderTime 71ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/JsonVisualizer/Internal/IncludeMicroParser.Json.cs

#
C# | 3485 lines | 2662 code | 521 blank | 302 comment | 174 complexity | 8d37ca31b129a7bc9d59f00c4aac4129 MD5 | raw file
  1. #define MICRO_PARSER_NET35
  2. #define MICRO_PARSER_JSON_NET35
  3. // ----------------------------------------------------------------------------
  4. // Included defines (C# requires #define to in the first part of a code file)
  5. // ----------------------------------------------------------------------------
  6. #define MICRO_PARSER_SUPPRESS_ANONYMOUS_TYPE
  7. #define MICRO_PARSER_SUPPRESS_CHAR_PARSER_MANY_CHAR_SATISFY_2
  8. #define MICRO_PARSER_SUPPRESS_CHAR_PARSER_SKIP_NEW_LINE
  9. #define MICRO_PARSER_SUPPRESS_CHAR_PARSER_SKIP_NONE_OF
  10. #define MICRO_PARSER_SUPPRESS_CHAR_SATISFY_COMPOSITES
  11. #define MICRO_PARSER_SUPPRESS_EXTENSIONS_EXCEPT
  12. #define MICRO_PARSER_SUPPRESS_EXTENSIONS_OR
  13. #define MICRO_PARSER_SUPPRESS_PARSER_CHAIN
  14. #define MICRO_PARSER_SUPPRESS_PARSER_COMBINE
  15. #define MICRO_PARSER_SUPPRESS_PARSER_EXCEPT
  16. #define MICRO_PARSER_SUPPRESS_PARSER_FAIL
  17. #define MICRO_PARSER_SUPPRESS_PARSER_FAIL_WITH_EXPECTED
  18. // ----------------------------------------------------------------------------
  19. // ----------------------------------------------------------------------------
  20. // Included code
  21. // ----------------------------------------------------------------------------
  22. // #define MICRO_PARSER_SUPPRESS_ANONYMOUS_TYPE
  23. // #define MICRO_PARSER_SUPPRESS_PARSER_CHAIN
  24. // #define MICRO_PARSER_SUPPRESS_PARSER_COMBINE
  25. // #define MICRO_PARSER_SUPPRESS_PARSER_EXCEPT
  26. // #define MICRO_PARSER_SUPPRESS_PARSER_FAIL
  27. // #define MICRO_PARSER_SUPPRESS_PARSER_FAIL_WITH_EXPECTED
  28. // #define MICRO_PARSER_SUPPRESS_CHAR_PARSER_MANY_CHAR_SATISFY_2
  29. // #define MICRO_PARSER_SUPPRESS_CHAR_PARSER_SKIP_NEW_LINE
  30. // #define MICRO_PARSER_SUPPRESS_CHAR_PARSER_SKIP_NONE_OF
  31. // #define MICRO_PARSER_SUPPRESS_CHAR_SATISFY_COMPOSITES
  32. // #define MICRO_PARSER_SUPPRESS_EXTENSIONS_EXCEPT
  33. // #define MICRO_PARSER_SUPPRESS_EXTENSIONS_OR
  34. // ----------------------------------------------------------------------------
  35. // Included code
  36. // ----------------------------------------------------------------------------
  37. namespace Include
  38. {
  39. // ----------------------------------------------------------------------------------------------
  40. // Copyright (c) Mårten Rånge.
  41. // ----------------------------------------------------------------------------------------------
  42. // This source code is subject to terms and conditions of the Microsoft Public License. A
  43. // copy of the license can be found in the License.html file at the root of this distribution.
  44. // If you cannot locate the Microsoft Public License, please send an email to
  45. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  46. // by the terms of the Microsoft Public License.
  47. // ----------------------------------------------------------------------------------------------
  48. // You must not remove this notice, or any other, from this software.
  49. // ----------------------------------------------------------------------------------------------
  50. namespace MicroParser
  51. {
  52. using System;
  53. using System.Linq;
  54. using Internal;
  55. static partial class CharParser
  56. {
  57. #if !MICRO_PARSER_SUPPRESS_CHAR_PARSER_SKIP_CHAR
  58. public static Parser<Empty> SkipChar (char toSkip)
  59. {
  60. return SkipString (new string (toSkip, 1));
  61. }
  62. #endif
  63. #if !MICRO_PARSER_SUPPRESS_CHAR_PARSER_SKIP_STRING
  64. public static Parser<Empty> SkipString (string toSkip)
  65. {
  66. if (toSkip.IsNullOrEmpty ())
  67. {
  68. throw new ArgumentNullException ("toSkip");
  69. }
  70. CharSatisfy.Function satisfy = (c, i) => c == toSkip[i];
  71. var parserErrorMessage = new ParserErrorMessage_Expected (Strings.CharSatisfy.FormatChar_1.FormatWith (toSkip));
  72. return SkipSatisfy (
  73. new CharSatisfy (parserErrorMessage, satisfy),
  74. toSkip.Length,
  75. toSkip.Length);
  76. }
  77. #endif
  78. #if !MICRO_PARSER_SUPPRESS_CHAR_PARSER_SKIP_ANY_OF
  79. public static Parser<Empty> SkipAnyOf (string skipAnyOfThese)
  80. {
  81. var sat = CharSatisfy.CreateSatisfyForAnyOf (skipAnyOfThese);
  82. return SkipSatisfy (
  83. sat,
  84. maxCount:1
  85. );
  86. }
  87. #endif
  88. #if !MICRO_PARSER_SUPPRESS_CHAR_PARSER_SKIP_NONE_OF
  89. public static Parser<Empty> SkipNoneOf (string skipNoneOfThese)
  90. {
  91. var sat = CharSatisfy.CreateSatisfyForNoneOf (skipNoneOfThese);
  92. return SkipSatisfy (
  93. sat,
  94. maxCount: 1
  95. );
  96. }
  97. #endif
  98. #if !MICRO_PARSER_SUPPRESS_CHAR_PARSER_SKIP_SATISFY
  99. public static Parser<Empty> SkipSatisfy (
  100. CharSatisfy charSatisfy,
  101. int minCount = 0,
  102. int maxCount = int.MaxValue
  103. )
  104. {
  105. Parser.VerifyMinAndMaxCount (minCount, maxCount);
  106. Parser<Empty>.Function function = state =>
  107. {
  108. var advanceResult = state.SkipAdvance (charSatisfy.Satisfy, minCount, maxCount);
  109. return ParserReply.Create (advanceResult, state, charSatisfy.ErrorMessage, Empty.Value);
  110. };
  111. return function;
  112. }
  113. #endif
  114. #if !MICRO_PARSER_SUPPRESS_CHAR_PARSER_SKIP_WHITE_SPACE
  115. public static Parser<Empty> SkipWhiteSpace (
  116. int minCount = 0,
  117. int maxCount = int.MaxValue
  118. )
  119. {
  120. return SkipSatisfy (CharSatisfy.WhiteSpace, minCount, maxCount);
  121. }
  122. #endif
  123. #if !MICRO_PARSER_SUPPRESS_CHAR_PARSER_SKIP_NEW_LINE
  124. public static Parser<Empty> SkipNewLine (
  125. )
  126. {
  127. return SkipChar ('\r').Opt ()
  128. .KeepRight (SkipChar ('\n'));
  129. }
  130. #endif
  131. #if !MICRO_PARSER_SUPPRESS_CHAR_PARSER_ANY_OF
  132. public static Parser<SubString> AnyOf (
  133. string match,
  134. int minCount = 0,
  135. int maxCount = int.MaxValue
  136. )
  137. {
  138. var satisfy = CharSatisfy.CreateSatisfyForAnyOf (match);
  139. return ManyCharSatisfy (satisfy, minCount, maxCount);
  140. }
  141. #endif
  142. #if !MICRO_PARSER_SUPPRESS_CHAR_PARSER_NONE_OF
  143. public static Parser<SubString> NoneOf (
  144. string match,
  145. int minCount = 0,
  146. int maxCount = int.MaxValue
  147. )
  148. {
  149. var satisfy = CharSatisfy.CreateSatisfyForNoneOf (match);
  150. return ManyCharSatisfy (satisfy, minCount, maxCount);
  151. }
  152. #endif
  153. #if !MICRO_PARSER_SUPPRESS_CHAR_PARSER_MANY_CHAR_SATISFY
  154. public static Parser<SubString> ManyCharSatisfy (
  155. CharSatisfy satisfy,
  156. int minCount = 0,
  157. int maxCount = int.MaxValue
  158. )
  159. {
  160. Parser.VerifyMinAndMaxCount (minCount, maxCount);
  161. Parser<SubString>.Function function = state =>
  162. {
  163. var subString = new SubString ();
  164. var advanceResult = state.Advance (ref subString, satisfy.Satisfy, minCount, maxCount);
  165. return ParserReply.Create (
  166. advanceResult,
  167. state,
  168. satisfy.ErrorMessage,
  169. subString
  170. );
  171. };
  172. return function;
  173. }
  174. #endif
  175. #if !MICRO_PARSER_SUPPRESS_CHAR_PARSER_MANY_CHAR_SATISFY_2
  176. public static Parser<SubString> ManyCharSatisfy2 (
  177. CharSatisfy satisfyFirst,
  178. CharSatisfy satisfyRest,
  179. int minCount = 0,
  180. int maxCount = int.MaxValue
  181. )
  182. {
  183. Parser.VerifyMinAndMaxCount (minCount, maxCount);
  184. var first = satisfyFirst.Satisfy;
  185. var rest = satisfyRest.Satisfy;
  186. CharSatisfy.Function satisfy = (c, i) => i == 0 ? first (c, i) : rest (c, i);
  187. Parser<SubString>.Function function = state =>
  188. {
  189. var subString = new SubString ();
  190. var advanceResult = state.Advance (ref subString, satisfy, minCount, maxCount);
  191. var expected =
  192. (advanceResult == ParserState.AdvanceResult.Error_EndOfStream_PostionChanged || advanceResult == ParserState.AdvanceResult.Error_SatisfyFailed_PositionChanged)
  193. ? satisfyRest.ErrorMessage
  194. : satisfyFirst.ErrorMessage;
  195. return ParserReply.Create (
  196. advanceResult,
  197. state,
  198. expected,
  199. subString
  200. );
  201. };
  202. return function;
  203. }
  204. #endif
  205. partial struct UIntResult
  206. {
  207. public uint Value;
  208. public int ConsumedCharacters;
  209. }
  210. static Parser<UIntResult> UIntImpl (
  211. int minCount = 1,
  212. int maxCount = 10
  213. )
  214. {
  215. Parser.VerifyMinAndMaxCount (minCount, maxCount);
  216. CharSatisfy.Function satisfy = (c, i) => char.IsDigit (c);
  217. Parser<UIntResult>.Function function = state =>
  218. {
  219. var subString = new SubString ();
  220. var oldPos = state.Position;
  221. var advanceResult = state.Advance (ref subString, satisfy, minCount, maxCount);
  222. var newPos = state.Position;
  223. return ParserReply.Create (
  224. advanceResult,
  225. state,
  226. ParserErrorMessages.Expected_Digit,
  227. () =>
  228. {
  229. var accumulated = 0u;
  230. var length = subString.Length;
  231. const uint c0 = (uint) '0';
  232. for (var iter = 0; iter < length; ++iter)
  233. {
  234. var c = subString[iter];
  235. accumulated = accumulated*10 + (c - c0);
  236. }
  237. return new UIntResult
  238. {
  239. Value = accumulated,
  240. ConsumedCharacters = newPos.Position - oldPos.Position,
  241. };
  242. }
  243. );
  244. };
  245. return function;
  246. }
  247. #if !MICRO_PARSER_SUPPRESS_CHAR_PARSER_HEX
  248. static uint? CharToHex (char ch)
  249. {
  250. if ('0' <= ch && ch <= '9')
  251. {
  252. return (uint?) (ch - '0');
  253. }
  254. else if ('A' <= ch && ch <= 'F')
  255. {
  256. return (uint?) (ch - 'A' + 0xA);
  257. }
  258. else if ('a' <= ch && ch <= 'f')
  259. {
  260. return (uint?)(ch - 'a' + 0xA);
  261. }
  262. else
  263. {
  264. return null;
  265. }
  266. }
  267. [CLSCompliant (false)]
  268. public static Parser<uint> Hex (
  269. int minCount = 1,
  270. int maxCount = 10
  271. )
  272. {
  273. Parser.VerifyMinAndMaxCount (minCount, maxCount);
  274. CharSatisfy.Function satisfy = (c, i) => CharToHex (c) != null;
  275. Parser<uint>.Function function = state =>
  276. {
  277. var subString = new SubString ();
  278. var advanceResult = state.Advance (ref subString, satisfy, minCount, maxCount);
  279. return ParserReply.Create (
  280. advanceResult,
  281. state,
  282. ParserErrorMessages.Expected_HexDigit,
  283. () =>
  284. {
  285. var accumulated = 0u;
  286. var length = subString.Length;
  287. for (var iter = 0; iter < length; ++iter)
  288. {
  289. var c = subString[iter];
  290. accumulated = accumulated * 0x10U + CharToHex (c).Value;
  291. }
  292. return accumulated;
  293. }
  294. );
  295. };
  296. return function;
  297. }
  298. #endif
  299. #if !MICRO_PARSER_SUPPRESS_CHAR_PARSER_UINT
  300. [CLSCompliant (false)]
  301. public static Parser<uint> UInt (
  302. int minCount = 1,
  303. int maxCount = 10
  304. )
  305. {
  306. var uintParser = UIntImpl (minCount, maxCount);
  307. Parser<uint>.Function function = state =>
  308. {
  309. var uintResult = uintParser.Execute (state);
  310. if (uintResult.State.HasError ())
  311. {
  312. return uintResult.Failure<uint> ();
  313. }
  314. return uintResult.Success (uintResult.Value.Value);
  315. };
  316. return function;
  317. }
  318. #endif
  319. #if !MICRO_PARSER_SUPPRESS_CHAR_PARSER_INT
  320. public static Parser<int> Int (
  321. )
  322. {
  323. var intParser = Parser.Group (
  324. SkipChar ('-').Opt (),
  325. UInt ()
  326. );
  327. Parser<int>.Function function = state =>
  328. {
  329. var intResult = intParser.Execute (state);
  330. if (intResult.State.HasError ())
  331. {
  332. return intResult.Failure<int> ();
  333. }
  334. var intValue = (int)intResult.Value.Item2;
  335. return intResult.Success (intResult.Value.Item1.HasValue ? -intValue : intValue);
  336. };
  337. return function;
  338. }
  339. #endif
  340. #if !MICRO_PARSER_SUPPRESS_CHAR_PARSER_DOUBLE
  341. public static Parser<double> Double ()
  342. {
  343. var intParser = Int ();
  344. var fracParser = SkipChar ('.').KeepRight (UIntImpl ());
  345. var expParser = SkipAnyOf ("eE").KeepRight (Parser.Group (AnyOf ("+-", maxCount:1), UInt ()));
  346. var doubleParser = Parser.Group (
  347. intParser,
  348. fracParser.Opt (),
  349. expParser.Opt ()
  350. );
  351. Parser<double>.Function function = state =>
  352. {
  353. var doubleResult = doubleParser.Execute (state);
  354. if (doubleResult.State.HasError ())
  355. {
  356. return doubleResult.Failure<double> ();
  357. }
  358. var value = doubleResult.Value;
  359. var intValue = value.Item1;
  360. double doubleValue;
  361. if (value.Item2.HasValue)
  362. {
  363. var uIntResult = value.Item2.Value;
  364. var multiplier = intValue >= 0 ? 1 : -1;
  365. doubleValue = intValue + multiplier * uIntResult.Value * (Math.Pow (0.1, uIntResult.ConsumedCharacters));
  366. }
  367. else
  368. {
  369. doubleValue = intValue;
  370. }
  371. if (value.Item3.HasValue)
  372. {
  373. var modifier = value.Item3.Value.Item1;
  374. var multiplier =
  375. modifier[0] == '-'
  376. ? -1.0
  377. : 1.0
  378. ;
  379. doubleValue *= Math.Pow (10.0, multiplier*value.Item3.Value.Item2);
  380. }
  381. return doubleResult.Success (doubleValue);
  382. };
  383. return function;
  384. }
  385. #endif
  386. }
  387. }
  388. }
  389. namespace Include
  390. {
  391. // ----------------------------------------------------------------------------------------------
  392. // Copyright (c) Mårten Rånge.
  393. // ----------------------------------------------------------------------------------------------
  394. // This source code is subject to terms and conditions of the Microsoft Public License. A
  395. // copy of the license can be found in the License.html file at the root of this distribution.
  396. // If you cannot locate the Microsoft Public License, please send an email to
  397. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  398. // by the terms of the Microsoft Public License.
  399. // ----------------------------------------------------------------------------------------------
  400. // You must not remove this notice, or any other, from this software.
  401. // ----------------------------------------------------------------------------------------------
  402. namespace MicroParser
  403. {
  404. using System;
  405. using System.Collections.Generic;
  406. using System.Linq;
  407. using System.Linq.Expressions;
  408. using Internal;
  409. sealed partial class CharSatisfy
  410. {
  411. public delegate bool Function (char ch, int index);
  412. public readonly IParserErrorMessage ErrorMessage;
  413. public readonly Function Satisfy;
  414. public static implicit operator CharSatisfy (char ch)
  415. {
  416. return new CharSatisfy (
  417. new ParserErrorMessage_Expected (Strings.CharSatisfy.FormatChar_1.FormatWith (ch)),
  418. (c, i) => ch == c
  419. );
  420. }
  421. public CharSatisfy (IParserErrorMessage errorMessage, Function satisfy)
  422. {
  423. ErrorMessage = errorMessage;
  424. Satisfy = satisfy;
  425. }
  426. #if !MICRO_PARSER_SUPPRESS_ANONYMOUS_TYPE
  427. public override string ToString ()
  428. {
  429. return new
  430. {
  431. ErrorMessage,
  432. }.ToString ();
  433. }
  434. #endif
  435. class SatisfyFunctions
  436. {
  437. // ReSharper disable MemberHidesStaticFromOuterClass
  438. // ReSharper disable MemberCanBeMadeStatic.Local
  439. // These methods should be kept non static as that reduces delegate overhead
  440. public bool AnyChar (char ch, int index)
  441. {
  442. return true;
  443. }
  444. public bool WhiteSpace (char ch, int index)
  445. {
  446. return char.IsWhiteSpace (ch);
  447. }
  448. public bool Digit (char ch, int index)
  449. {
  450. return char.IsDigit (ch);
  451. }
  452. public bool Letter (char ch, int index)
  453. {
  454. return char.IsLetter (ch);
  455. }
  456. // ReSharper restore MemberCanBeMadeStatic.Local
  457. // ReSharper restore MemberHidesStaticFromOuterClass
  458. }
  459. static readonly SatisfyFunctions s_satisfyFunctions = new SatisfyFunctions ();
  460. public static readonly CharSatisfy AnyChar = new CharSatisfy (ParserErrorMessages.Expected_Any , s_satisfyFunctions.AnyChar );
  461. public static readonly CharSatisfy WhiteSpace = new CharSatisfy (ParserErrorMessages.Expected_WhiteSpace , s_satisfyFunctions.WhiteSpace );
  462. public static readonly CharSatisfy Digit = new CharSatisfy (ParserErrorMessages.Expected_Digit , s_satisfyFunctions.Digit );
  463. public static readonly CharSatisfy Letter = new CharSatisfy (ParserErrorMessages.Expected_Letter , s_satisfyFunctions.Letter );
  464. public static readonly CharSatisfy LineBreak = new CharSatisfy (ParserErrorMessages.Expected_LineBreak , CreateSatisfyFunctionForAnyOfOrNoneOf ("\r\n", true));
  465. #if !MICRO_PARSER_SUPPRESS_CHAR_SATISFY_COMPOSITES
  466. public static readonly CharSatisfy LineBreakOrWhiteSpace = LineBreak.Or (WhiteSpace);
  467. public static readonly CharSatisfy LetterOrDigit = Letter.Or (Digit);
  468. #endif
  469. #if MICRO_PARSER_NET35
  470. static Function CreateSatisfyFunctionForAnyOfOrNoneOf (
  471. string match,
  472. bool matchResult
  473. )
  474. {
  475. if (!match.Any (ch => ch > 255))
  476. {
  477. var boolMap = Enumerable.Repeat (!matchResult, 256).ToArray ();
  478. foreach (var c in match)
  479. {
  480. boolMap[c] = matchResult;
  481. }
  482. return (c, i) => ((c & 0xFF00) == 0) && boolMap[c & 0xFF];
  483. }
  484. #if WINDOWS_PHONE
  485. // Windows Phone is basically .NET35 but lacks the HashSet class.
  486. // Approximate with Dictionary<>
  487. var dictionary = match.ToDictionary (v => v, v => true);
  488. return (c, i) => dictionary.ContainsKey (c) ? matchResult : !matchResult;
  489. #else
  490. var hashSet = new HashSet<char> (match);
  491. return (c, i) => hashSet.Contains (c) ? matchResult : !matchResult;
  492. #endif
  493. }
  494. #else
  495. static Function CreateSatisfyFunctionForAnyOfOrNoneOf (
  496. string match,
  497. bool matchResult
  498. )
  499. {
  500. // For input string "Test" this generates the equivalent code to
  501. // Func<char, int> d = (ch, index) =>
  502. // {
  503. // bool result;
  504. // switch (ch)
  505. // {
  506. // case 'T':
  507. // case 'e':
  508. // case 's':
  509. // case 't':
  510. // result = matchResult;
  511. // break;
  512. // default:
  513. // result = !matchResult;
  514. // break;
  515. // }
  516. // return result;
  517. // }
  518. var parameter0 = Expression.Parameter (typeof (char), "ch");
  519. var parameter1 = Expression.Parameter (typeof (int), "index");
  520. var resultVariable = Expression.Variable (typeof (bool), "result");
  521. var switchStatement = Expression.Switch (
  522. parameter0,
  523. Expression.Assign (resultVariable, Expression.Constant (!matchResult)),
  524. Expression.SwitchCase (
  525. Expression.Assign (resultVariable, Expression.Constant (matchResult)),
  526. match.Select (ch => Expression.Constant (ch)).ToArray ()
  527. ));
  528. var body = Expression.Block (
  529. new[] { resultVariable },
  530. switchStatement,
  531. resultVariable
  532. );
  533. var lambda = Expression.Lambda<Function>(
  534. body,
  535. parameter0,
  536. parameter1
  537. );
  538. return lambda.Compile ();
  539. }
  540. #endif
  541. static CharSatisfy CreateSatisfyForAnyOfOrNoneOf (
  542. string match,
  543. Func<char, IParserErrorMessage> action,
  544. bool matchResult
  545. )
  546. {
  547. if (match.IsNullOrEmpty ())
  548. {
  549. throw new ArgumentNullException ("match");
  550. }
  551. var errorMessages = match
  552. .Select (action)
  553. .ToArray ()
  554. ;
  555. return new CharSatisfy (
  556. new ParserErrorMessage_Group (errorMessages),
  557. CreateSatisfyFunctionForAnyOfOrNoneOf (match, matchResult)
  558. );
  559. }
  560. public static CharSatisfy CreateSatisfyForAnyOf (string match)
  561. {
  562. return CreateSatisfyForAnyOfOrNoneOf (
  563. match,
  564. x => new ParserErrorMessage_Expected (Strings.CharSatisfy.FormatChar_1.FormatWith (x)),
  565. true
  566. );
  567. }
  568. public static CharSatisfy CreateSatisfyForNoneOf (string match)
  569. {
  570. return CreateSatisfyForAnyOfOrNoneOf (
  571. match,
  572. x => new ParserErrorMessage_Unexpected (Strings.CharSatisfy.FormatChar_1.FormatWith (x)),
  573. false
  574. );
  575. }
  576. }
  577. }
  578. }
  579. namespace Include
  580. {
  581. // ----------------------------------------------------------------------------------------------
  582. // Copyright (c) Mårten Rånge.
  583. // ----------------------------------------------------------------------------------------------
  584. // This source code is subject to terms and conditions of the Microsoft Public License. A
  585. // copy of the license can be found in the License.html file at the root of this distribution.
  586. // If you cannot locate the Microsoft Public License, please send an email to
  587. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  588. // by the terms of the Microsoft Public License.
  589. // ----------------------------------------------------------------------------------------------
  590. // You must not remove this notice, or any other, from this software.
  591. // ----------------------------------------------------------------------------------------------
  592. namespace MicroParser
  593. {
  594. partial struct Empty
  595. {
  596. public static Empty Value;
  597. public override string ToString ()
  598. {
  599. return Strings.Empty;
  600. }
  601. }
  602. }
  603. }
  604. namespace Include
  605. {
  606. // ----------------------------------------------------------------------------------------------
  607. // Copyright (c) Mårten Rånge.
  608. // ----------------------------------------------------------------------------------------------
  609. // This source code is subject to terms and conditions of the Microsoft Public License. A
  610. // copy of the license can be found in the License.html file at the root of this distribution.
  611. // If you cannot locate the Microsoft Public License, please send an email to
  612. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  613. // by the terms of the Microsoft Public License.
  614. // ----------------------------------------------------------------------------------------------
  615. // You must not remove this notice, or any other, from this software.
  616. // ----------------------------------------------------------------------------------------------
  617. namespace MicroParser
  618. {
  619. using System.Collections.Generic;
  620. using System.Linq;
  621. static partial class Extensions
  622. {
  623. // ParserReply.State
  624. public static bool IsSuccessful (this ParserReply.State state)
  625. {
  626. return state == ParserReply.State.Successful;
  627. }
  628. public static bool HasConsistentState (this ParserReply.State state)
  629. {
  630. return
  631. (state & ParserReply.State.FatalError_StateIsNotRestored)
  632. == 0;
  633. }
  634. public static bool HasFatalError (this ParserReply.State state)
  635. {
  636. return state >= ParserReply.State.FatalError;
  637. }
  638. public static bool HasError (this ParserReply.State state)
  639. {
  640. return state >= ParserReply.State.Error;
  641. }
  642. public static bool HasNonFatalError (this ParserReply.State state)
  643. {
  644. return state >= ParserReply.State.Error && state < ParserReply.State.FatalError;
  645. }
  646. // IParserErrorMessage
  647. public static IEnumerable<IParserErrorMessage> DeepTraverse (this IParserErrorMessage value)
  648. {
  649. if (value == null)
  650. {
  651. yield break;
  652. }
  653. var stack = new Stack<IParserErrorMessage> ();
  654. stack.Push (value);
  655. while (stack.Count > 0)
  656. {
  657. var pop = stack.Pop ();
  658. var parserErrorMessageGroup = pop as ParserErrorMessage_Group;
  659. if (parserErrorMessageGroup != null && parserErrorMessageGroup.Group != null)
  660. {
  661. foreach (var parserErrorMessage in parserErrorMessageGroup.Group)
  662. {
  663. stack.Push (parserErrorMessage);
  664. }
  665. }
  666. else if (pop != null)
  667. {
  668. yield return pop;
  669. }
  670. }
  671. }
  672. public static IParserErrorMessage Append (this IParserErrorMessage left, IParserErrorMessage right)
  673. {
  674. return new ParserErrorMessage_Group (
  675. left.DeepTraverse ().Concat (right.DeepTraverse ()).ToArray ()
  676. );
  677. }
  678. // CharSatisfy
  679. #if !MICRO_PARSER_SUPPRESS_EXTENSIONS_OR
  680. public static CharSatisfy Or (this CharSatisfy first, CharSatisfy second)
  681. {
  682. return new CharSatisfy (
  683. first.ErrorMessage.Append (second.ErrorMessage),
  684. (c, i) => first.Satisfy (c, i) || second.Satisfy (c, i)
  685. );
  686. }
  687. #endif
  688. #if !MICRO_PARSER_SUPPRESS_EXTENSIONS_EXCEPT
  689. static IParserErrorMessage ExpectedToUnexpected (
  690. IParserErrorMessage parserErrorMessage
  691. )
  692. {
  693. var parserErrorMessageExpected = parserErrorMessage as ParserErrorMessage_Expected;
  694. return parserErrorMessageExpected != null
  695. ? new ParserErrorMessage_Unexpected (parserErrorMessageExpected.Expected)
  696. : parserErrorMessage
  697. ;
  698. }
  699. public static CharSatisfy Except (this CharSatisfy first, CharSatisfy second)
  700. {
  701. return new CharSatisfy (
  702. first.ErrorMessage.Append (ExpectedToUnexpected (second.ErrorMessage)),
  703. (c, i) => first.Satisfy (c, i) && !second.Satisfy (c, i)
  704. );
  705. }
  706. #endif
  707. }
  708. }
  709. }
  710. namespace Include
  711. {
  712. // ----------------------------------------------------------------------------------------------
  713. // Copyright (c) Mårten Rånge.
  714. // ----------------------------------------------------------------------------------------------
  715. // This source code is subject to terms and conditions of the Microsoft Public License. A
  716. // copy of the license can be found in the License.html file at the root of this distribution.
  717. // If you cannot locate the Microsoft Public License, please send an email to
  718. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  719. // by the terms of the Microsoft Public License.
  720. // ----------------------------------------------------------------------------------------------
  721. // You must not remove this notice, or any other, from this software.
  722. // ----------------------------------------------------------------------------------------------
  723. namespace MicroParser.Internal
  724. {
  725. using System;
  726. using System.Collections.Generic;
  727. using System.Globalization;
  728. using System.Text;
  729. static partial class Extensions
  730. {
  731. // System.String
  732. public static string FormatWith (this string format, params object[] args)
  733. {
  734. return string.Format (CultureInfo.InvariantCulture, format, args);
  735. }
  736. public static bool IsNullOrEmpty (this string str)
  737. {
  738. return string.IsNullOrEmpty (str);
  739. }
  740. // IEnumerable<string>
  741. public static string Concatenate (
  742. this IEnumerable<string> strings,
  743. string delimiter = null,
  744. string prepend = null,
  745. string append = null
  746. )
  747. {
  748. var first = true;
  749. var sb = new StringBuilder (prepend ?? String.Empty);
  750. var del = delimiter ?? String.Empty;
  751. foreach (var value in strings)
  752. {
  753. if (first)
  754. {
  755. first = false;
  756. }
  757. else
  758. {
  759. sb.Append (del);
  760. }
  761. sb.Append (value);
  762. }
  763. sb.Append (append ?? String.Empty);
  764. return sb.ToString ();
  765. }
  766. }
  767. }
  768. }
  769. namespace Include
  770. {
  771. // ----------------------------------------------------------------------------------------------
  772. // Copyright (c) Mårten Rånge.
  773. // ----------------------------------------------------------------------------------------------
  774. // This source code is subject to terms and conditions of the Microsoft Public License. A
  775. // copy of the license can be found in the License.html file at the root of this distribution.
  776. // If you cannot locate the Microsoft Public License, please send an email to
  777. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  778. // by the terms of the Microsoft Public License.
  779. // ----------------------------------------------------------------------------------------------
  780. // You must not remove this notice, or any other, from this software.
  781. // ----------------------------------------------------------------------------------------------
  782. namespace MicroParser
  783. {
  784. #if MICRO_PARSER_MAKE_PUBLIC
  785. public partial class CharParser
  786. {
  787. }
  788. public partial class CharSatisfy
  789. {
  790. }
  791. public partial interface IParserErrorMessage
  792. {
  793. }
  794. public partial struct Empty
  795. {
  796. }
  797. public partial class Extensions
  798. {
  799. }
  800. public partial class Optional
  801. {
  802. }
  803. public partial struct Optional<TValue>
  804. {
  805. }
  806. public partial class Parser<TValue>
  807. {
  808. }
  809. public partial class Parser
  810. {
  811. }
  812. public partial class ParserFunctionRedirect<TValue>
  813. {
  814. }
  815. public partial class ParserReply
  816. {
  817. }
  818. public partial struct ParserReply<TValue>
  819. {
  820. }
  821. public partial class BaseParserResult
  822. {
  823. }
  824. public partial class ParserResult<TValue>
  825. {
  826. }
  827. public partial class ParserState
  828. {
  829. }
  830. public partial struct ParserStatePosition
  831. {
  832. }
  833. public partial struct SubString
  834. {
  835. }
  836. #if MICRO_PARSER_NET35
  837. public partial class Tuple
  838. {
  839. }
  840. public partial struct Tuple<TValue1, TValue2>
  841. {
  842. }
  843. public partial struct Tuple<TValue1, TValue2, TValue3>
  844. {
  845. }
  846. #endif
  847. #endif
  848. }
  849. }
  850. namespace Include
  851. {
  852. // ----------------------------------------------------------------------------------------------
  853. // Copyright (c) Mårten Rånge.
  854. // ----------------------------------------------------------------------------------------------
  855. // This source code is subject to terms and conditions of the Microsoft Public License. A
  856. // copy of the license can be found in the License.html file at the root of this distribution.
  857. // If you cannot locate the Microsoft Public License, please send an email to
  858. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  859. // by the terms of the Microsoft Public License.
  860. // ----------------------------------------------------------------------------------------------
  861. // You must not remove this notice, or any other, from this software.
  862. // ----------------------------------------------------------------------------------------------
  863. namespace MicroParser
  864. {
  865. static partial class Optional
  866. {
  867. public static Optional<TValue> Create<TValue> (TValue value)
  868. {
  869. return new Optional<TValue> (value);
  870. }
  871. public static Optional<TValue> Create<TValue> ()
  872. {
  873. return new Optional<TValue> ();
  874. }
  875. }
  876. partial struct Optional<TValue>
  877. {
  878. public readonly bool HasValue;
  879. public readonly TValue Value;
  880. public Optional (TValue value)
  881. {
  882. HasValue = true;
  883. Value = value;
  884. }
  885. #if !MICRO_PARSER_SUPPRESS_ANONYMOUS_TYPE
  886. public override string ToString ()
  887. {
  888. return new
  889. {
  890. HasValue,
  891. Value = HasValue ? Value : default (TValue),
  892. }.ToString ();
  893. }
  894. #endif
  895. }
  896. }
  897. }
  898. namespace Include
  899. {
  900. // ----------------------------------------------------------------------------------------------
  901. // Copyright (c) Mårten Rånge.
  902. // ----------------------------------------------------------------------------------------------
  903. // This source code is subject to terms and conditions of the Microsoft Public License. A
  904. // copy of the license can be found in the License.html file at the root of this distribution.
  905. // If you cannot locate the Microsoft Public License, please send an email to
  906. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  907. // by the terms of the Microsoft Public License.
  908. // ----------------------------------------------------------------------------------------------
  909. // You must not remove this notice, or any other, from this software.
  910. // ----------------------------------------------------------------------------------------------
  911. namespace MicroParser
  912. {
  913. using System;
  914. using System.Collections.Generic;
  915. using System.Diagnostics;
  916. using System.Linq;
  917. using Internal;
  918. sealed partial class Parser<TValue>
  919. {
  920. // ParserState is basically a string with a position
  921. // ParserReply contains the updated state and the result of the parser
  922. // operation depending on if the operation was successful
  923. public delegate ParserReply<TValue> Function (ParserState state);
  924. public readonly Function Execute;
  925. public Parser (Function function)
  926. {
  927. if (function == null)
  928. {
  929. throw new ArgumentNullException ("function");
  930. }
  931. Execute = function;
  932. }
  933. public static implicit operator Parser<TValue> (Function function)
  934. {
  935. return new Parser<TValue> (function);
  936. }
  937. }
  938. static partial class Parser
  939. {
  940. public static ParserResult<TValue> Parse<TValue> (Parser<TValue> parserFunction, string text)
  941. {
  942. var parseResult = parserFunction.Execute (
  943. ParserState.Create (
  944. text ?? Strings.Empty,
  945. suppressParserErrorMessageOperations:true
  946. ));
  947. if (!parseResult.State.IsSuccessful ())
  948. {
  949. var parseResultWithErrorInfo = parserFunction.Execute (
  950. ParserState.Create (
  951. text ?? Strings.Empty
  952. ));
  953. var errorResult = parseResultWithErrorInfo
  954. .ParserErrorMessage
  955. .DeepTraverse ()
  956. .GroupBy (msg => msg.Description)
  957. .OrderBy (group => group.Key)
  958. .Select (group =>
  959. Strings.Parser.ErrorMessage_2.FormatWith (
  960. group.Key,
  961. group.Select (message => message.Value.ToString ()).Distinct ().OrderBy (v => v).Concatenate (", ")
  962. ))
  963. .Concatenate (", ");
  964. var subString = new SubString (
  965. text,
  966. parseResultWithErrorInfo.ParserState.InternalPosition
  967. );
  968. var completeErrorResult =
  969. "Pos: {0} ('{1}') - {2}".FormatWith (
  970. subString.Position,
  971. subString[0],
  972. errorResult
  973. );
  974. return new ParserResult<TValue> (
  975. false,
  976. subString,
  977. completeErrorResult,
  978. default (TValue)
  979. );
  980. }
  981. return new ParserResult<TValue> (
  982. true,
  983. new SubString (
  984. text,
  985. parseResult.ParserState.InternalPosition
  986. ),
  987. Strings.Empty,
  988. parseResult.Value
  989. );
  990. }
  991. #if !MICRO_PARSER_SUPPRESS_PARSER_REDIRECT
  992. public static ParserFunctionRedirect<TValue> Redirect<TValue> ()
  993. {
  994. return new ParserFunctionRedirect<TValue> ();
  995. }
  996. #endif
  997. #if !MICRO_PARSER_SUPPRESS_PARSER_RETURN
  998. public static Parser<TValue> Return<TValue> (TValue value)
  999. {
  1000. Parser<TValue>.Function function = state => ParserReply<TValue>.Success (state, value);
  1001. return function;
  1002. }
  1003. #endif
  1004. #if !MICRO_PARSER_SUPPRESS_PARSER_FAIL
  1005. public static Parser<TValue> Fail<TValue>(string message)
  1006. {
  1007. var parserErrorMessageMessage = new ParserErrorMessage_Message (message);
  1008. Parser<TValue>.Function function = state => ParserReply<TValue>.Failure (ParserReply.State.Error, state, parserErrorMessageMessage);
  1009. return function;
  1010. }
  1011. #endif
  1012. #if !MICRO_PARSER_SUPPRESS_PARSER_FAIL_WITH_EXPECTED
  1013. public static Parser<TValue> FailWithExpected<TValue>(this Parser<TValue> parser, string message)
  1014. {
  1015. var parserErrorMessageMessage = new ParserErrorMessage_Expected (message);
  1016. Parser<TValue>.Function function =
  1017. state =>
  1018. {
  1019. var reply = parser.Execute (state);
  1020. if (reply.State.HasError ())
  1021. {
  1022. return ParserReply<TValue>.Failure(
  1023. ParserReply.State.Error_Expected | reply.State & ParserReply.State.FatalError_Mask,
  1024. state,
  1025. parserErrorMessageMessage
  1026. );
  1027. }
  1028. return reply;
  1029. };
  1030. return function;
  1031. }
  1032. #endif
  1033. #if !MICRO_PARSER_SUPPRESS_PARSER_DEBUG_BREAK
  1034. public static Parser<TValue> DebugBreak<TValue> (this Parser<TValue> parser)
  1035. {
  1036. Parser<TValue>.Function function =
  1037. state =>
  1038. {
  1039. Debug.Assert (false);
  1040. return parser.Execute (state);
  1041. };
  1042. return function;
  1043. }
  1044. #endif
  1045. #if !MICRO_PARSER_SUPPRESS_PARSER_END_OF_STREAM
  1046. public static Parser<Empty> EndOfStream ()
  1047. {
  1048. Parser<Empty>.Function function = state =>
  1049. state.EndOfStream
  1050. ? ParserReply<Empty>.Success (state, Empty.Value)
  1051. : ParserReply<Empty>.Failure (
  1052. ParserReply.State.Error_Expected,
  1053. state,
  1054. ParserErrorMessages.Expected_EndOfStream
  1055. );
  1056. return function;
  1057. }
  1058. #endif
  1059. #if !MICRO_PARSER_SUPPRESS_PARSER_COMBINE
  1060. public static Parser<TValue2> Combine<TValue, TValue2>(this Parser<TValue> firstParser, Func<TValue, Parser<TValue2>> second)
  1061. {
  1062. Parser<TValue2>.Function function = state =>
  1063. {
  1064. var firstResult = firstParser.Execute (state);
  1065. if (firstResult.State.HasError ())
  1066. {
  1067. return firstResult.Failure<TValue2> ();
  1068. }
  1069. var secondParser = second (firstResult.Value);
  1070. var secondResult = secondParser.Execute (state);
  1071. return secondResult;
  1072. };
  1073. return function;
  1074. }
  1075. #endif
  1076. #if !MICRO_PARSER_SUPPRESS_PARSER_MAP
  1077. public static Parser<TValue2> Map<TValue1, TValue2> (this Parser<TValue1> firstParser, Func<TValue1, TValue2> mapper)
  1078. {
  1079. Parser<TValue2>.Function function = state =>
  1080. {
  1081. var firstResult = firstParser.Execute (state);
  1082. if (firstResult.State.HasError ())
  1083. {
  1084. return firstResult.Failure<TValue2> ();
  1085. }
  1086. return firstResult.Success (mapper (firstResult.Value));
  1087. };
  1088. return function;
  1089. }
  1090. public static Parser<TValue2> Map<TValue1, TValue2> (this Parser<TValue1> firstParser, TValue2 value2)
  1091. {
  1092. return firstParser.Map (ignore => value2);
  1093. }
  1094. #endif
  1095. #if !MICRO_PARSER_SUPPRESS_PARSER_CHAIN
  1096. public static Parser<TValue1> Chain<TValue1, TValue2>(
  1097. this Parser<TValue1> parser,
  1098. Parser<TValue2> separator,
  1099. Func<TValue1, TValue2, TValue1, TValue1> combiner
  1100. )
  1101. {
  1102. Parser<TValue1>.Function function = state =>
  1103. {
  1104. var result = parser.Execute (state);
  1105. if (result.State.HasError ())
  1106. {
  1107. return result;
  1108. }
  1109. var accu = result.Value;
  1110. ParserReply<TValue2> separatorResult;
  1111. while ((separatorResult = separator.Execute (state)).State.IsSuccessful ())
  1112. {
  1113. var trailingResult = parser.Execute (state);
  1114. if (trailingResult.State.HasError ())
  1115. {
  1116. return trailingResult;
  1117. }
  1118. accu = combiner (accu, separatorResult.Value, trailingResult.Value);
  1119. }
  1120. if (separatorResult.State.HasFatalError ())
  1121. {
  1122. return separatorResult.Failure<TValue1> ();
  1123. }
  1124. return ParserReply<TValue1>.Success (state, accu);
  1125. };
  1126. return function;
  1127. }
  1128. #endif
  1129. #if !MICRO_PARSER_SUPPRESS_PARSER_ARRAY
  1130. public static Parser<TValue[]> Array<TValue> (
  1131. this Parser<TValue> parser,
  1132. Parser<Empty> separator,
  1133. bool allowTrailingSeparator = false,
  1134. int minCount = 0,
  1135. int maxCount = int.MaxValue
  1136. )
  1137. {
  1138. VerifyMinAndMaxCount (minCount, maxCount);
  1139. Parser<TValue[]>.Function function = state =>
  1140. {
  1141. var initialPosition = state.Position;
  1142. var result = new List<TValue> (Math.Max (minCount, 16));
  1143. // Collect required
  1144. for (var iter = 0; iter < minCount; ++iter)
  1145. {
  1146. if (result.Count > 0)
  1147. {
  1148. var separatorResult = separator.Execute (state);
  1149. if (separatorResult.State.HasError ())
  1150. {
  1151. return separatorResult.Failure<TValue[]> ().VerifyConsistency (initialPosition);
  1152. }
  1153. }
  1154. var parserResult = parser.Execute (state);
  1155. if (parserResult.State.HasError ())
  1156. {
  1157. return parserResult.Failure<TValue[]> ().VerifyConsistency (initialPosition);
  1158. }
  1159. result.Add (parserResult.Value);
  1160. }
  1161. // Collect optional
  1162. for (var iter = minCount; iter < maxCount; ++iter)
  1163. {
  1164. if (result.Count > 0)
  1165. {
  1166. var separatorResult = separator.Execute (state);
  1167. if (separatorResult.State.HasFatalError ())
  1168. {
  1169. return separatorResult.Failure<TValue[]> ().VerifyConsistency (initialPosition);
  1170. }
  1171. else if (separatorResult.State.HasError ())
  1172. {
  1173. break;
  1174. }
  1175. }
  1176. var parserResult = parser.Execute (state);
  1177. if (!allowTrailingSeparator && result.Count > 0)
  1178. {
  1179. // If a separator has been consumed we need to fail on failures
  1180. if (parserResult.State.HasError())
  1181. {
  1182. return parserResult.Failure<TValue[]> ().VerifyConsistency (initialPosition);
  1183. }
  1184. }
  1185. else
  1186. {
  1187. // If a separator has not been consumed we only need to fail on fatal errors
  1188. if (parserResult.State.HasFatalError ())
  1189. {
  1190. return parserResult.Failure<TValue[]> ().VerifyConsistency (initialPosition);
  1191. }
  1192. else if (parserResult.State.HasError ())
  1193. {
  1194. break;
  1195. }
  1196. }
  1197. result.Add (parserResult.Value);
  1198. }
  1199. return ParserReply<TValue[]>.Success (state, result.ToArray ());
  1200. };
  1201. return function;
  1202. }
  1203. #endif
  1204. #if !MICRO_PARSER_SUPPRESS_PARSER_MANY
  1205. public static Parser<TValue[]> Many<TValue> (
  1206. this Parser<TValue> parser,
  1207. int minCount = 0,
  1208. int maxCount = int.MaxValue
  1209. )
  1210. {
  1211. VerifyMinAndMaxCount (minCount, maxCount);
  1212. Parser<TValue[]>.Function function = state =>
  1213. {
  1214. var initialPosition = state.Position;
  1215. var result = new List<TValue> (Math.Max (minCount, 16));
  1216. // Collect required
  1217. for (var iter = 0; iter < minCount; ++iter)
  1218. {
  1219. var parserResult = parser.Execute (state);
  1220. if (parserResult.State.HasError ())
  1221. {
  1222. return parserResult.Failure<TValue[]> ().VerifyConsistency (initialPosition);
  1223. }
  1224. result.Add (parserResult.Value);
  1225. }
  1226. // Collect optional
  1227. for (var iter = minCount; iter < maxCount; ++iter)
  1228. {
  1229. var parserResult = parser.Execute (state);
  1230. if (parserResult.State.HasFatalError ())
  1231. {
  1232. return parserResult.Failure<TValue[]> ().VerifyConsistency (initialPosition);
  1233. }
  1234. else if (parserResult.State.HasError ())
  1235. {
  1236. break;
  1237. }
  1238. result.Add (parserResult.Value);
  1239. }
  1240. return ParserReply<TValue[]>.Success (state, result.ToArray ());
  1241. };
  1242. return function;
  1243. }
  1244. #endif
  1245. #if !MICRO_PARSER_SUPPRESS_PARSER_SWITCH
  1246. public enum SwitchCharacterBehavior
  1247. {
  1248. Consume ,
  1249. Leave ,
  1250. }
  1251. public struct SwitchCase<TValue>
  1252. {
  1253. public readonly string Case;
  1254. public readonly Parser<TValue> Parser;
  1255. public readonly string Expected;
  1256. public SwitchCase (string @case, Parser<TValue> parser, string expected) : this()
  1257. {
  1258. Case = @case ?? "";
  1259. Parser = parser ;
  1260. Expected = expected ?? "";
  1261. }
  1262. }
  1263. public static SwitchCase<TValue> Case<TValue> (
  1264. string @case,
  1265. Parser<TValue> parser,
  1266. string expected = null
  1267. )
  1268. {
  1269. return new SwitchCase<TValue>(@case, parser, expected);
  1270. }
  1271. public static Parser<TValue> Switch<TValue> (
  1272. SwitchCharacterBehavior switchCharacterBehavior,
  1273. params SwitchCase<TValue>[] cases
  1274. )
  1275. {
  1276. if (cases == null)
  1277. {
  1278. throw new ArgumentNullException ("cases");
  1279. }
  1280. if (cases.Length == 0)
  1281. {
  1282. throw new ArgumentOutOfRangeException ("cases", Strings.Parser.Verify_AtLeastOneParserFunctions);
  1283. }
  1284. var caseDictionary = cases
  1285. .SelectMany ((@case, i) => @case.Case.Select (c => Tuple.Create (c, i)))
  1286. .ToDictionary (kv => kv.Item1, kv => kv.Item2);
  1287. var errorMessages = cases
  1288. .SelectMany(
  1289. (@case, i) => @case.Expected.IsNullOrEmpty()
  1290. ? @case
  1291. .Case
  1292. .Select(ch => Strings.CharSatisfy.FormatChar_1.FormatWith(ch))
  1293. : new[] { @case.Expected })
  1294. .Distinct ()
  1295. .Select (message => new ParserErrorMessage_Expected (message))
  1296. .ToArray();
  1297. var errorMessage = new ParserErrorMessage_Group (
  1298. errorMessages
  1299. );
  1300. Parser<TValue>.Function function = state =>
  1301. {
  1302. var initialPosition = state.Position;
  1303. var peeked = state.PeekChar ();
  1304. if (peeked == null)
  1305. {
  1306. return ParserReply<TValue>.Failure (
  1307. ParserReply.State.Error_Unexpected,
  1308. state,
  1309. ParserErrorMessages.Unexpected_Eos
  1310. );
  1311. }
  1312. var peekedValue = peeked.Value;
  1313. int index;
  1314. if (!caseDictionary.TryGetValue (peekedValue, out index))
  1315. {
  1316. return ParserReply<TValue>.Failure (
  1317. ParserReply.State.Error_Expected,
  1318. state,
  1319. errorMessage
  1320. );
  1321. }
  1322. if (switchCharacterBehavior == SwitchCharacterBehavior.Consume)
  1323. {
  1324. // Intentionally ignores result as SkipAdvance can't fail
  1325. // in this situation (we know ParserState has at least one character left)
  1326. state.SkipAdvance (1);
  1327. }
  1328. return cases[index].Parser.Execute(
  1329. state
  1330. )
  1331. .VerifyConsistency(initialPosition);
  1332. };
  1333. return function;
  1334. }
  1335. #endif
  1336. #if !MICRO_PARSER_SUPPRESS_PARSER_CHOICE
  1337. public static Parser<TValue> Choice<TValue> (
  1338. params Parser<TValue>[] parserFunctions
  1339. )
  1340. {
  1341. if (parserFunctions == null)
  1342. {
  1343. throw new ArgumentNullException ("parserFunctions");
  1344. }
  1345. if (parserFunctions.Length == 0)
  1346. {
  1347. throw new ArgumentOutOfRangeException ("parserFunctions", Strings.Parser.Verify_AtLeastOneParserFunctions);
  1348. }
  1349. Parser<TValue>.Function function = state =>
  1350. {
  1351. var suppressParserErrorMessageOperations = state.SuppressParserErrorMessageOperations;
  1352. var potentialErrors =
  1353. !suppressParserErrorMessageOperations
  1354. ? new List<IParserErrorMessage> (parserFunctions.Length)
  1355. : null
  1356. ;
  1357. foreach (var parserFunction in parserFunctions)
  1358. {
  1359. var result = parserFunction.Execute (state);
  1360. if (result.State.IsSuccessful ())
  1361. {
  1362. return result;
  1363. }
  1364. else if (result.State.HasFatalError ())
  1365. {
  1366. return result;
  1367. }
  1368. else if (!suppressParserErrorMessageOperations)
  1369. {
  1370. potentialErrors.Add (result.ParserErrorMessage);
  1371. }
  1372. }
  1373. if (!suppressParserErrorMessageOperations)
  1374. {
  1375. var topGroup = new ParserErrorMessage_Group (potentialErrors.ToArray ());
  1376. return ParserReply<TValue>.Failure (ParserReply.State.Error_Group, state, topGroup);
  1377. }
  1378. return ParserReply<TValue>.Failure (ParserReply.State.Error_Expected, state, ParserErrorMessages.Expected_Choice);
  1379. };
  1380. return function;
  1381. }
  1382. #endif
  1383. #if !MICRO_PARSER_SUPPRESS_PARSER_KEEP_LEFT
  1384. public static Parser<TValue1> KeepLeft<TValue1, TValue2> (
  1385. this Parser<TValue1> firstParser,
  1386. Parser<TValue2> secondParser
  1387. )
  1388. {
  1389. Parser<TValue1>.Function function = state =>
  1390. {
  1391. var initialPosition = state.Position;
  1392. var firstResult = firstParser.Execute (state);
  1393. if (firstResult.State.HasError ())
  1394. {
  1395. return firstResult;
  1396. }
  1397. var secondResult = secondParser.Execute (state);
  1398. if (secondResult.State.HasError ())
  1399. {
  1400. return secondResult.Failure<TValue1> ().VerifyConsistency (initialPosition);
  1401. }
  1402. return firstResult.Success (secondResult.ParserState);
  1403. };
  1404. return function;
  1405. }
  1406. #endif
  1407. #if !MICRO_PARSER_SUPPRESS_PARSER_KEEP_RIGHT
  1408. public static Parser<TValue2> KeepRight<TValue1, TValue2> (
  1409. this Parser<TValue1> firstParser,
  1410. Parser<TValue2> secondParser
  1411. )
  1412. {
  1413. Parser<TValue2>.Function function = state =>
  1414. {
  1415. var firstResult = firstParser.Execute (state);
  1416. if (firstResult.State.HasError ())
  1417. {
  1418. return firstResult.Failure<TValue2> ();
  1419. }
  1420. return secondParser.Execute (state);
  1421. };
  1422. return function;
  1423. }
  1424. #endif
  1425. #if !MICRO_PARSER_SUPPRESS_PARSER_ATTEMPT
  1426. public static Parser<TValue> Attempt<TValue>(
  1427. this Parser<TValue> firstParser
  1428. )
  1429. {
  1430. Parser<TValue>.Function function = state =>
  1431. {
  1432. var backupPosition = state.InternalPosition;
  1433. var firstResult = firstParser.Execute (state);
  1434. if (!firstResult.State.HasConsistentState ())
  1435. {
  1436. ParserState.RestorePosition (state, backupPosition);
  1437. return ParserReply<TValue>.Failure (
  1438. ParserReply.State.Error_StateIsRestored,
  1439. state,
  1440. firstResult.ParserErrorMessage
  1441. );
  1442. }
  1443. #if DEBUG
  1444. else
  1445. {
  1446. Debug.Assert (backupPosition == state.InternalPosition);
  1447. }
  1448. #endif
  1449. return firstResult;
  1450. };
  1451. return function;
  1452. }
  1453. #endif
  1454. #if !MICRO_PARSER_SUPPRESS_PARSER_OPT
  1455. public static Parser<Optional<TValue>> Opt<TValue> (
  1456. this Parser<TValue> firstParser
  1457. )
  1458. {
  1459. Parser<Optional<TValue>>.Function function = state =>
  1460. {
  1461. var firstResult = firstParser.Execute (state);
  1462. if (firstResult.State.IsSuccessful ())
  1463. {
  1464. return firstResult.Success (Optional.Create (firstResult.Value));
  1465. }
  1466. if (firstResult.State.HasNonFatalError ())
  1467. {
  1468. return firstResult.Success (Optional.Create<TValue> ());
  1469. }
  1470. return firstResult.Failure<Optional<TValue>> ();
  1471. };
  1472. return function;
  1473. }
  1474. #endif
  1475. #if !MICRO_PARSER_SUPPRESS_PARSER_BETWEEN
  1476. public static Parser<TValue> Between<TValue> (
  1477. this Parser<TValue> middleParser,
  1478. Parser<Empty> preludeParser,
  1479. Parser<Empty> epilogueParser
  1480. )
  1481. {
  1482. Parser<TValue>.Function function = state =>
  1483. {
  1484. var initialPosition = state.Position;
  1485. var preludeResult = preludeParser.Execute (state);
  1486. if (preludeResult.State.HasError ())
  1487. {
  1488. return preludeResult.Failure<TValue> ();
  1489. }
  1490. var middleResult = middleParser.Execute (state);
  1491. if (middleResult.State.HasError ())
  1492. {
  1493. return middleResult.VerifyConsistency (initialPosition);
  1494. }
  1495. var epilogueResult = epilogueParser.Execute (state);
  1496. if (epilogueResult.State.HasError ())
  1497. {
  1498. return epilogueResult.Failure<TValue> ().VerifyConsistency (initialPosition);
  1499. }
  1500. return middleResult.Success (epilogueResult.ParserState);
  1501. };
  1502. return function;
  1503. }
  1504. #endif
  1505. #if !MICRO_PARSER_SUPPRESS_PARSER_EXCEPT
  1506. public static Parser<TValue> Except<TValue> (
  1507. this Parser<TValue> parser,
  1508. Parser<Empty> exceptParser
  1509. )
  1510. {
  1511. Parser<TValue>.Function function = state =>
  1512. {
  1513. var exceptResult = exceptParser.Execute (state);
  1514. if (exceptResult.State.IsSuccessful ())
  1515. {
  1516. return ParserReply<TValue>.Failure (
  1517. ParserReply.State.Error_Unexpected,
  1518. exceptResult.ParserState,
  1519. ParserErrorMessages.Message_TODO
  1520. );
  1521. }
  1522. else if (exceptResult.State.HasFatalError ())
  1523. {
  1524. return exceptResult.Failure<TValue> ();
  1525. }
  1526. return parser.Execute (state);
  1527. };
  1528. return function;
  1529. }
  1530. #endif
  1531. internal static void VerifyMinAndMaxCount (int minCount, int maxCount)
  1532. {
  1533. if (minCount > maxCount)
  1534. {
  1535. throw new ArgumentOutOfRangeException ("minCount", Strings.Parser.Verify_MinCountAndMaxCount);
  1536. }
  1537. }
  1538. }
  1539. }
  1540. }
  1541. namespace Include
  1542. {
  1543. // ----------------------------------------------------------------------------------------------
  1544. // Copyright (c) M�rten R�nge.
  1545. // ----------------------------------------------------------------------------------------------
  1546. // This source code is subject to terms and conditions of the Microsoft Public License. A
  1547. // copy of the license can be found in the License.html file at the root of this distribution.
  1548. // If you cannot locate the Microsoft Public License, please send an email to
  1549. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  1550. // by the terms of the Microsoft Public License.
  1551. // ----------------------------------------------------------------------------------------------
  1552. // You must not remove this notice, or any other, from this software.
  1553. // ----------------------------------------------------------------------------------------------
  1554. // ReSharper disable InconsistentNaming
  1555. namespace MicroParser
  1556. {
  1557. using System;
  1558. using System.Linq;
  1559. using Internal;
  1560. partial interface IParserErrorMessage
  1561. {
  1562. string Description { get; }
  1563. object Value { get; }
  1564. }
  1565. abstract partial class ParserErrorMessage : IParserErrorMessage
  1566. {
  1567. public abstract string Description { get; }
  1568. public abstract object Value { get; }
  1569. }
  1570. static partial class ParserErrorMessages
  1571. {
  1572. [Obsolete]
  1573. public readonly static IParserErrorMessage Message_TODO = new ParserErrorMessage_Message (Strings.ParserErrorMessages.Todo);
  1574. public readonly static IParserErrorMessage Message_Unknown = new ParserErrorMessage_Message (Strings.ParserErrorMessages.Unknown);
  1575. public readonly static IParserErrorMessage Expected_EndOfStream = new ParserErrorMessage_Expected (Strings.ParserErrorMessages.Eos);
  1576. public readonly static IParserErrorMessage Expected_Digit = new ParserErrorMessage_Expected (Strings.ParserErrorMessages.Digit);
  1577. public readonly static IParserErrorMessage Expected_HexDigit = new ParserErrorMessage_Expected (Strings.ParserErrorMessages.HexDigit);
  1578. public readonly static IParserErrorMessage Expected_WhiteSpace = new ParserErrorMessage_Expected (Strings.ParserErrorMessages.WhiteSpace);
  1579. public readonly static IParserErrorMessage Expected_Choice = new ParserErrorMessage_Expected (Strings.ParserErrorMessages.Choice);
  1580. public readonly static IParserErrorMessage Expected_Any = new ParserErrorMessage_Expected (Strings.ParserErrorMessages.Any);
  1581. public readonly static IParserErrorMessage Expected_Letter = new ParserErrorMessage_Expected (Strings.ParserErrorMessages.Letter);
  1582. public readonly static IParserErrorMessage Expected_LineBreak = new ParserErrorMessage_Expected (Strings.ParserErrorMessages.LineBreak);
  1583. public readonly static IParserErrorMessage Unexpected_Eos = new ParserErrorMessage_Unexpected (Strings.ParserErrorMessages.Eos);
  1584. }
  1585. sealed partial class ParserErrorMessage_Message : ParserErrorMessage
  1586. {
  1587. public readonly string Message;
  1588. public ParserErrorMessage_Message (string message)
  1589. {
  1590. Message = message;
  1591. }
  1592. public override string ToString ()
  1593. {
  1594. return Strings.ParserErrorMessages.Message_1.FormatWith (Message);
  1595. }
  1596. public override string Description
  1597. {
  1598. get { return Strings.ParserErrorMessages.Message; }
  1599. }
  1600. public override object Value
  1601. {
  1602. get { return Message; }
  1603. }
  1604. }
  1605. sealed partial class ParserErrorMessage_Expected : ParserErrorMessage
  1606. {
  1607. public readonly string Expected;
  1608. public ParserErrorMessage_Expected (string expected)
  1609. {
  1610. Expected = expected;
  1611. }
  1612. public override string ToString ()
  1613. {
  1614. return Strings.ParserErrorMessages.Expected_1.FormatWith (Expected);
  1615. }
  1616. public override string Description
  1617. {
  1618. get { return Strings.ParserErrorMessages.Expected; }
  1619. }
  1620. public override object Value
  1621. {
  1622. get { return Expected; }
  1623. }
  1624. }
  1625. sealed partial class ParserErrorMessage_Unexpected : ParserErrorMessage
  1626. {
  1627. public readonly string Unexpected;
  1628. public ParserErrorMessage_Unexpected (string unexpected)
  1629. {
  1630. Unexpected = unexpected;
  1631. }
  1632. public override string ToString ()
  1633. {
  1634. return Strings.ParserErrorMessages.Unexpected_1.FormatWith (Unexpected);
  1635. }
  1636. public override string Description
  1637. {
  1638. get { return Strings.ParserErrorMessages.Unexpected; }
  1639. }
  1640. public override object Value
  1641. {
  1642. get { return Unexpected; }
  1643. }
  1644. }
  1645. sealed partial class ParserErrorMessage_Group : ParserErrorMessage
  1646. {
  1647. public readonly IParserErrorMessage[] Group;
  1648. public ParserErrorMessage_Group (IParserErrorMessage[] group)
  1649. {
  1650. Group = group;
  1651. }
  1652. public override string ToString ()
  1653. {
  1654. return Strings.ParserErrorMessages.Group_1.FormatWith (Group.Select (message => message.ToString ()).Concatenate (Strings.CommaSeparator));
  1655. }
  1656. public override string Description
  1657. {
  1658. get { return Strings.ParserErrorMessages.Group; }
  1659. }
  1660. public override object Value
  1661. {
  1662. get { return Strings.ParserErrorMessages.Group; }
  1663. }
  1664. }
  1665. }
  1666. }
  1667. namespace Include
  1668. {
  1669. // ----------------------------------------------------------------------------------------------
  1670. // Copyright (c) Mårten Rånge.
  1671. // ----------------------------------------------------------------------------------------------
  1672. // This source code is subject to terms and conditions of the Microsoft Public License. A
  1673. // copy of the license can be found in the License.html file at the root of this distribution.
  1674. // If you cannot locate the Microsoft Public License, please send an email to
  1675. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  1676. // by the terms of the Microsoft Public License.
  1677. // ----------------------------------------------------------------------------------------------
  1678. // You must not remove this notice, or any other, from this software.
  1679. // ----------------------------------------------------------------------------------------------
  1680. namespace MicroParser
  1681. {
  1682. sealed partial class ParserFunctionRedirect<TValue>
  1683. {
  1684. public readonly Parser<TValue> Parser;
  1685. public Parser<TValue> ParserRedirect;
  1686. public ParserFunctionRedirect ()
  1687. {
  1688. Parser<TValue> .Function function = state => ParserRedirect.Execute (state);
  1689. Parser = function;
  1690. }
  1691. }
  1692. }
  1693. }
  1694. namespace Include
  1695. {
  1696. // ----------------------------------------------------------------------------------------------
  1697. // Copyright (c) Mårten Rånge.
  1698. // ----------------------------------------------------------------------------------------------
  1699. // This source code is subject to terms and conditions of the Microsoft Public License. A
  1700. // copy of the license can be found in the License.html file at the root of this distribution.
  1701. // If you cannot locate the Microsoft Public License, please send an email to
  1702. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  1703. // by the terms of the Microsoft Public License.
  1704. // ----------------------------------------------------------------------------------------------
  1705. // You must not remove this notice, or any other, from this software.
  1706. // ----------------------------------------------------------------------------------------------
  1707. namespace MicroParser
  1708. {
  1709. using System;
  1710. using MicroParser.Internal;
  1711. partial class Parser
  1712. {
  1713. #if !MICRO_PARSER_SUPPRESS_PARSER_GROUP_2
  1714. public static Parser<Tuple<TValue1, TValue2>> Group<TValue1, TValue2> (
  1715. Parser<TValue1> parser1
  1716. , Parser<TValue2> parser2
  1717. )
  1718. {
  1719. Parser<Tuple<TValue1, TValue2>>.Function function = state =>
  1720. {
  1721. var initialPosition = state.Position;
  1722. var result1 = parser1.Execute (state);
  1723. if (result1.State.HasError ())
  1724. {
  1725. return result1.Failure<Tuple<TValue1, TValue2>>().VerifyConsistency (initialPosition);
  1726. }
  1727. var result2 = parser2.Execute (state);
  1728. if (result2.State.HasError ())
  1729. {
  1730. return result2.Failure<Tuple<TValue1, TValue2>>().VerifyConsistency (initialPosition);
  1731. }
  1732. return result2.Success (
  1733. Tuple.Create (
  1734. result1.Value
  1735. , result2.Value
  1736. ));
  1737. };
  1738. return function;
  1739. }
  1740. #endif
  1741. #if !MICRO_PARSER_SUPPRESS_PARSER_GROUP_3
  1742. public static Parser<Tuple<TValue1, TValue2, TValue3>> Group<TValue1, TValue2, TValue3> (
  1743. Parser<TValue1> parser1
  1744. , Parser<TValue2> parser2
  1745. , Parser<TValue3> parser3
  1746. )
  1747. {
  1748. Parser<Tuple<TValue1, TValue2, TValue3>>.Function function = state =>
  1749. {
  1750. var initialPosition = state.Position;
  1751. var result1 = parser1.Execute (state);
  1752. if (result1.State.HasError ())
  1753. {
  1754. return result1.Failure<Tuple<TValue1, TValue2, TValue3>>().VerifyConsistency (initialPosition);
  1755. }
  1756. var result2 = parser2.Execute (state);
  1757. if (result2.State.HasError ())
  1758. {
  1759. return result2.Failure<Tuple<TValue1, TValue2, TValue3>>().VerifyConsistency (initialPosition);
  1760. }
  1761. var result3 = parser3.Execute (state);
  1762. if (result3.State.HasError ())
  1763. {
  1764. return result3.Failure<Tuple<TValue1, TValue2, TValue3>>().VerifyConsistency (initialPosition);
  1765. }
  1766. return result3.Success (
  1767. Tuple.Create (
  1768. result1.Value
  1769. , result2.Value
  1770. , result3.Value
  1771. ));
  1772. };
  1773. return function;
  1774. }
  1775. #endif
  1776. }
  1777. }
  1778. }
  1779. namespace Include
  1780. {
  1781. // ----------------------------------------------------------------------------------------------
  1782. // Copyright (c) Mårten Rånge.
  1783. // ----------------------------------------------------------------------------------------------
  1784. // This source code is subject to terms and conditions of the Microsoft Public License. A
  1785. // copy of the license can be found in the License.html file at the root of this distribution.
  1786. // If you cannot locate the Microsoft Public License, please send an email to
  1787. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  1788. // by the terms of the Microsoft Public License.
  1789. // ----------------------------------------------------------------------------------------------
  1790. // You must not remove this notice, or any other, from this software.
  1791. // ----------------------------------------------------------------------------------------------
  1792. namespace MicroParser
  1793. {
  1794. using Internal;
  1795. using System;
  1796. using System.Diagnostics;
  1797. static partial class ParserReply
  1798. {
  1799. // ReSharper disable InconsistentNaming
  1800. [Flags]
  1801. public enum State
  1802. {
  1803. Successful = 00,
  1804. Error = 10,
  1805. Error_Message = 11,
  1806. Error_Expected = 12,
  1807. Error_Unexpected = 13,
  1808. Error_Group = 14,
  1809. Error_StateIsRestored = 15,
  1810. Error_Mask = 0x0000FFFF,
  1811. FatalError = 0x00010000,
  1812. FatalError_Mask = 0x7FFF0000,
  1813. FatalError_Terminate = 0x00010000,
  1814. FatalError_StateIsNotRestored = 0x00020000,
  1815. }
  1816. // ReSharper restore InconsistentNaming
  1817. static ParserReply<TValue> CreateParserReplyFailure<TValue>(ParserState.AdvanceResult advanceResult, ParserState state, IParserErrorMessage parserErrorMessage)
  1818. {
  1819. switch (advanceResult)
  1820. {
  1821. case ParserState.AdvanceResult.Error_EndOfStream:
  1822. return ParserReply<TValue>.Failure (State.Error_Unexpected, state, ParserErrorMessages.Unexpected_Eos);
  1823. case ParserState.AdvanceResult.Error_SatisfyFailed:
  1824. return ParserReply<TValue>.Failure (State.Error, state, parserErrorMessage);
  1825. case ParserState.AdvanceResult.Error_EndOfStream_PostionChanged:
  1826. return ParserReply<TValue>.Failure (State.FatalError_StateIsNotRestored | State.Error_Unexpected, state, ParserErrorMessages.Unexpected_Eos);
  1827. case ParserState.AdvanceResult.Error_SatisfyFailed_PositionChanged:
  1828. return ParserReply<TValue>.Failure (State.FatalError_StateIsNotRestored | State.Error, state, parserErrorMessage);
  1829. case ParserState.AdvanceResult.Error:
  1830. default:
  1831. return ParserReply<TValue>.Failure (State.Error, state, ParserErrorMessages.Message_Unknown);
  1832. }
  1833. }
  1834. public static ParserReply<TValue> Create<TValue>(
  1835. ParserState.AdvanceResult advanceResult,
  1836. ParserState state,
  1837. IParserErrorMessage parserErrorMessage,
  1838. TValue value
  1839. )
  1840. {
  1841. return advanceResult == ParserState.AdvanceResult.Successful
  1842. ? ParserReply<TValue>.Success (state, value)
  1843. : CreateParserReplyFailure<TValue>(advanceResult, state, parserErrorMessage)
  1844. ;
  1845. }
  1846. public static ParserReply<TValue> Create<TValue>(
  1847. ParserState.AdvanceResult advanceResult,
  1848. ParserState state,
  1849. IParserErrorMessage parserErrorMessage,
  1850. Func<TValue> valueCreator
  1851. )
  1852. {
  1853. return advanceResult == ParserState.AdvanceResult.Successful
  1854. ? ParserReply<TValue>.Success (state, valueCreator ())
  1855. : CreateParserReplyFailure<TValue>(advanceResult, state, parserErrorMessage)
  1856. ;
  1857. }
  1858. }
  1859. partial struct ParserReply<TValue>
  1860. {
  1861. public readonly ParserReply.State State;
  1862. public readonly ParserState ParserState;
  1863. public readonly IParserErrorMessage ParserErrorMessage;
  1864. public readonly TValue Value;
  1865. ParserReply (ParserReply.State state, ParserState parserState, TValue value, IParserErrorMessage parserErrorMessage)
  1866. {
  1867. State = state;
  1868. ParserState = parserState;
  1869. ParserErrorMessage = parserErrorMessage;
  1870. Value = value;
  1871. }
  1872. public static ParserReply<TValue> Success (
  1873. ParserState parserState,
  1874. TValue value
  1875. )
  1876. {
  1877. return new ParserReply<TValue>(
  1878. ParserReply.State.Successful,
  1879. parserState,
  1880. value,
  1881. null
  1882. );
  1883. }
  1884. public static ParserReply<TValue> Failure (
  1885. ParserReply.State state,
  1886. ParserState parserState,
  1887. IParserErrorMessage parserErrorMessage
  1888. )
  1889. {
  1890. Debug.Assert (!state.IsSuccessful ());
  1891. Debug.Assert (parserErrorMessage != null);
  1892. return new ParserReply<TValue>(
  1893. state.IsSuccessful () ? ParserReply.State.Error : state,
  1894. parserState,
  1895. default (TValue),
  1896. parserErrorMessage
  1897. );
  1898. }
  1899. public ParserReply<TValueTo> Failure<TValueTo> ()
  1900. {
  1901. return ParserReply<TValueTo>.Failure (State, ParserState, ParserErrorMessage);
  1902. }
  1903. public ParserReply<TValue> Success (ParserState parserState)
  1904. {
  1905. return Success (parserState, Value);
  1906. }
  1907. public ParserReply<TValueTo> Success<TValueTo> (TValueTo valueTo)
  1908. {
  1909. return ParserReply<TValueTo>.Success (ParserState, valueTo);
  1910. }
  1911. public ParserReply<TValue> Failure (ParserState parserState)
  1912. {
  1913. return Failure (
  1914. State,
  1915. parserState,
  1916. ParserErrorMessage
  1917. );
  1918. }
  1919. public ParserReply<TValue> VerifyConsistency (ParserStatePosition initialPosition)
  1920. {
  1921. if (
  1922. State.HasError ()
  1923. && ParserState.InternalPosition - initialPosition.Position > 0
  1924. )
  1925. {
  1926. return new ParserReply<TValue>(
  1927. ParserReply.State.FatalError_StateIsNotRestored | State,
  1928. ParserState,
  1929. default (TValue),
  1930. ParserErrorMessage
  1931. );
  1932. }
  1933. return this;
  1934. }
  1935. #if !MICRO_PARSER_SUPPRESS_ANONYMOUS_TYPE
  1936. public override string ToString ()
  1937. {
  1938. if (State == ParserReply.State.Successful)
  1939. {
  1940. return new
  1941. {
  1942. State,
  1943. ParserState,
  1944. Value,
  1945. }.ToString ();
  1946. }
  1947. else
  1948. {
  1949. return new
  1950. {
  1951. State,
  1952. ParserState,
  1953. ParserErrorMessage,
  1954. }.ToString ();
  1955. }
  1956. }
  1957. #endif
  1958. }
  1959. }
  1960. }
  1961. namespace Include
  1962. {
  1963. // ----------------------------------------------------------------------------------------------
  1964. // Copyright (c) Mårten Rånge.
  1965. // ----------------------------------------------------------------------------------------------
  1966. // This source code is subject to terms and conditions of the Microsoft Public License. A
  1967. // copy of the license can be found in the License.html file at the root of this distribution.
  1968. // If you cannot locate the Microsoft Public License, please send an email to
  1969. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  1970. // by the terms of the Microsoft Public License.
  1971. // ----------------------------------------------------------------------------------------------
  1972. // You must not remove this notice, or any other, from this software.
  1973. // ----------------------------------------------------------------------------------------------
  1974. namespace MicroParser
  1975. {
  1976. abstract partial class BaseParserResult
  1977. {
  1978. public readonly bool IsSuccessful;
  1979. public readonly SubString Unconsumed;
  1980. public readonly string ErrorMessage;
  1981. public bool EndOfStream
  1982. {
  1983. get
  1984. {
  1985. return !(Unconsumed.Begin < Unconsumed.End);
  1986. }
  1987. }
  1988. protected BaseParserResult (bool isSuccessful, SubString unconsumed, string errorMessage)
  1989. {
  1990. IsSuccessful = isSuccessful;
  1991. Unconsumed = unconsumed;
  1992. ErrorMessage = errorMessage ?? Strings.Empty;
  1993. }
  1994. #if !MICRO_PARSER_SUPPRESS_ANONYMOUS_TYPE
  1995. public override string ToString ()
  1996. {
  1997. if (IsSuccessful)
  1998. {
  1999. return new
  2000. {
  2001. IsSuccessful,
  2002. Position = Unconsumed.Begin,
  2003. EndOfStream,
  2004. Current = !EndOfStream ? new string (Unconsumed[Unconsumed.Begin], 1) : Strings.ParserErrorMessages.Eos,
  2005. Value = GetValue (),
  2006. }.ToString ();
  2007. }
  2008. else
  2009. {
  2010. return new
  2011. {
  2012. IsSuccessful,
  2013. Position = Unconsumed.Begin,
  2014. EndOfStream,
  2015. Current = !EndOfStream ? new string (Unconsumed[Unconsumed.Begin], 1) : Strings.ParserErrorMessages.Eos,
  2016. ErrorMessage,
  2017. }.ToString ();
  2018. }
  2019. }
  2020. #endif
  2021. protected abstract object GetValue ();
  2022. }
  2023. sealed partial class ParserResult<TValue> : BaseParserResult
  2024. {
  2025. public readonly TValue Value;
  2026. public ParserResult (bool isSuccessful, SubString subString, string errorMessage, TValue value)
  2027. : base (isSuccessful, subString, errorMessage)
  2028. {
  2029. Value = value;
  2030. }
  2031. protected override object GetValue ()
  2032. {
  2033. return Value;
  2034. }
  2035. }
  2036. }
  2037. }
  2038. namespace Include
  2039. {
  2040. // ----------------------------------------------------------------------------------------------
  2041. // Copyright (c) Mårten Rånge.
  2042. // ----------------------------------------------------------------------------------------------
  2043. // This source code is subject to terms and conditions of the Microsoft Public License. A
  2044. // copy of the license can be found in the License.html file at the root of this distribution.
  2045. // If you cannot locate the Microsoft Public License, please send an email to
  2046. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  2047. // by the terms of the Microsoft Public License.
  2048. // ----------------------------------------------------------------------------------------------
  2049. // You must not remove this notice, or any other, from this software.
  2050. // ----------------------------------------------------------------------------------------------
  2051. namespace MicroParser
  2052. {
  2053. using System;
  2054. using System.Diagnostics;
  2055. partial struct ParserStatePosition
  2056. {
  2057. public readonly int Position;
  2058. public ParserStatePosition (int position)
  2059. {
  2060. Position = position;
  2061. }
  2062. #if !MICRO_PARSER_SUPPRESS_ANONYMOUS_TYPE
  2063. public override string ToString ()
  2064. {
  2065. return new
  2066. {
  2067. Position,
  2068. }.ToString ();
  2069. }
  2070. #endif
  2071. }
  2072. sealed partial class ParserState
  2073. {
  2074. // ReSharper disable InconsistentNaming
  2075. public enum AdvanceResult
  2076. {
  2077. Successful = 00,
  2078. Error = 10,
  2079. Error_EndOfStream = 11,
  2080. Error_SatisfyFailed = 12,
  2081. Error_EndOfStream_PostionChanged = 23,
  2082. Error_SatisfyFailed_PositionChanged = 24,
  2083. }
  2084. // ReSharper restore InconsistentNaming
  2085. readonly string m_text;
  2086. int m_position;
  2087. public readonly bool SuppressParserErrorMessageOperations;
  2088. ParserState (int position, string text, bool suppressParserErrorMessageOperations)
  2089. {
  2090. m_position = Math.Max (position, 0);
  2091. m_text = text ?? String.Empty;
  2092. SuppressParserErrorMessageOperations = suppressParserErrorMessageOperations;
  2093. }
  2094. internal int InternalPosition
  2095. {
  2096. get
  2097. {
  2098. return m_position;
  2099. }
  2100. }
  2101. public string Text
  2102. {
  2103. get
  2104. {
  2105. return m_text;
  2106. }
  2107. }
  2108. public ParserStatePosition Position
  2109. {
  2110. get
  2111. {
  2112. return new ParserStatePosition (m_position);
  2113. }
  2114. }
  2115. public bool EndOfStream
  2116. {
  2117. get
  2118. {
  2119. return !(m_position < m_text.Length);
  2120. }
  2121. }
  2122. public char? PeekChar ()
  2123. {
  2124. if (EndOfStream)
  2125. {
  2126. return null;
  2127. }
  2128. return m_text[m_position];
  2129. }
  2130. public AdvanceResult Advance (
  2131. ref SubString subString,
  2132. CharSatisfy.Function satisfy,
  2133. int minCount = 1,
  2134. int maxCount = int.MaxValue
  2135. )
  2136. {
  2137. Debug.Assert (minCount <= maxCount);
  2138. var localSatisfy = satisfy ?? CharSatisfy.AnyChar.Satisfy;
  2139. subString.Value = m_text;
  2140. subString.Position = m_position;
  2141. /*
  2142. * This optimization is very tempting to do, but this will give the wrong error message
  2143. * The optimization only saves time at the end of stream so it was removed
  2144. if (m_position + minCount >= m_text.Length + 1)
  2145. {
  2146. return AdvanceResult.Error_EndOfStream;
  2147. }
  2148. */
  2149. var length = Math.Min (maxCount, m_text.Length - m_position);
  2150. for (var iter = 0; iter < length; ++iter)
  2151. {
  2152. var c = m_text[m_position];
  2153. if (!localSatisfy (c, iter))
  2154. {
  2155. if (iter < minCount)
  2156. {
  2157. return subString.Position == m_position
  2158. ? AdvanceResult.Error_SatisfyFailed
  2159. : AdvanceResult.Error_SatisfyFailed_PositionChanged
  2160. ;
  2161. }
  2162. subString.Length = m_position - subString.Position;
  2163. return AdvanceResult.Successful;
  2164. }
  2165. ++m_position;
  2166. }
  2167. subString.Length = m_position - subString.Position;
  2168. if (length < minCount)
  2169. {
  2170. return subString.Position == m_position
  2171. ? AdvanceResult.Error_SatisfyFailed
  2172. : AdvanceResult.Error_SatisfyFailed_PositionChanged
  2173. ;
  2174. }
  2175. return AdvanceResult.Successful;
  2176. }
  2177. public AdvanceResult SkipAdvance (int count)
  2178. {
  2179. if (m_position + count >= m_text.Length + 1)
  2180. {
  2181. return AdvanceResult.Error_EndOfStream;
  2182. }
  2183. m_position += count;
  2184. return AdvanceResult.Successful;
  2185. }
  2186. public AdvanceResult SkipAdvance (
  2187. CharSatisfy.Function satisfy,
  2188. int minCount = 1,
  2189. int maxCount = int.MaxValue
  2190. )
  2191. {
  2192. var subString = new SubString ();
  2193. return Advance (ref subString, satisfy, minCount, maxCount);
  2194. }
  2195. #if !MICRO_PARSER_SUPPRESS_ANONYMOUS_TYPE
  2196. public override string ToString ()
  2197. {
  2198. return new
  2199. {
  2200. Position = m_position,
  2201. SuppressParserErrorMessageOperations,
  2202. EndOfStream,
  2203. Current = !EndOfStream ? new string (m_text[m_position], 1) : Strings.ParserErrorMessages.Eos,
  2204. }.ToString ();
  2205. }
  2206. #endif
  2207. public static ParserState Create (
  2208. string text,
  2209. int position = 0,
  2210. bool suppressParserErrorMessageOperations = false
  2211. )
  2212. {
  2213. return new ParserState (
  2214. Math.Max (position, 0),
  2215. text ?? Strings.Empty,
  2216. suppressParserErrorMessageOperations
  2217. );
  2218. }
  2219. public static ParserState Clone (ParserState parserState)
  2220. {
  2221. if (parserState == null)
  2222. {
  2223. return null;
  2224. }
  2225. return new ParserState (
  2226. parserState.m_position,
  2227. parserState.m_text,
  2228. parserState.SuppressParserErrorMessageOperations
  2229. );
  2230. }
  2231. public static void Restore (ParserState parserState, ParserState clone)
  2232. {
  2233. if (parserState == null)
  2234. {
  2235. return;
  2236. }
  2237. if (clone == null)
  2238. {
  2239. return;
  2240. }
  2241. parserState.m_position = clone.m_position;
  2242. }
  2243. internal static void RestorePosition (ParserState parserState, int position)
  2244. {
  2245. if (parserState == null)
  2246. {
  2247. return;
  2248. }
  2249. parserState.m_position = position;
  2250. }
  2251. }
  2252. }
  2253. }
  2254. namespace Include
  2255. {
  2256. // ----------------------------------------------------------------------------------------------
  2257. // Copyright (c) Mårten Rånge.
  2258. // ----------------------------------------------------------------------------------------------
  2259. // This source code is subject to terms and conditions of the Microsoft Public License. A
  2260. // copy of the license can be found in the License.html file at the root of this distribution.
  2261. // If you cannot locate the Microsoft Public License, please send an email to
  2262. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  2263. // by the terms of the Microsoft Public License.
  2264. // ----------------------------------------------------------------------------------------------
  2265. // You must not remove this notice, or any other, from this software.
  2266. // ----------------------------------------------------------------------------------------------
  2267. // ReSharper disable InconsistentNaming
  2268. namespace MicroParser
  2269. {
  2270. using System;
  2271. static partial class Strings
  2272. {
  2273. public const string CommaSeparator = ", ";
  2274. public const string Empty = "";
  2275. public static class Parser
  2276. {
  2277. public const string ErrorMessage_2 = "{0} : {1}";
  2278. public const string Verify_AtLeastOneParserFunctions = "cases should contain at least 1 item";
  2279. public const string Verify_MinCountAndMaxCount = "minCount need to be less or equal to maxCount";
  2280. }
  2281. public static class CharSatisfy
  2282. {
  2283. public const string FormatChar_1 = "'{0}'";
  2284. }
  2285. public static class ParserErrorMessages
  2286. {
  2287. public const string Message_1 = "Message:{0}";
  2288. public const string Expected_1 = "Expected:{0}";
  2289. public const string Unexpected_1 = "Unexpected:{0}";
  2290. public const string Group_1 = "Group:{0}";
  2291. [Obsolete]
  2292. public const string Todo = "TODO:";
  2293. public const string Unexpected = "unexpected ";
  2294. public const string Unknown = "unknown error";
  2295. public const string Eos = "end of stream";
  2296. public const string WhiteSpace = "whitespace";
  2297. public const string Digit = "digit";
  2298. public const string HexDigit = "hexdigit";
  2299. public const string Letter = "letter";
  2300. public const string Any = "any";
  2301. public const string LineBreak = "linebreak";
  2302. public const string Choice = "multiple choices";
  2303. public const string Message = "message";
  2304. public const string Group = "group";
  2305. public const string Expected = "expected";
  2306. }
  2307. }
  2308. }
  2309. }
  2310. namespace Include
  2311. {
  2312. // ----------------------------------------------------------------------------------------------
  2313. // Copyright (c) Mårten Rånge.
  2314. // ----------------------------------------------------------------------------------------------
  2315. // This source code is subject to terms and conditions of the Microsoft Public License. A
  2316. // copy of the license can be found in the License.html file at the root of this distribution.
  2317. // If you cannot locate the Microsoft Public License, please send an email to
  2318. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  2319. // by the terms of the Microsoft Public License.
  2320. // ----------------------------------------------------------------------------------------------
  2321. // You must not remove this notice, or any other, from this software.
  2322. // ----------------------------------------------------------------------------------------------
  2323. namespace MicroParser
  2324. {
  2325. using System;
  2326. using System.Diagnostics;
  2327. using System.Text;
  2328. partial struct SubString : IEquatable<SubString>
  2329. {
  2330. public string Value;
  2331. public int Position;
  2332. public int Length;
  2333. public static implicit operator SubString (string s)
  2334. {
  2335. return new SubString (s);
  2336. }
  2337. public SubString (string value, int position, int length)
  2338. {
  2339. Value = value;
  2340. Position = position;
  2341. Length = length;
  2342. }
  2343. public SubString (string value, int position = 0)
  2344. : this (value, position, (value ?? Strings.Empty).Length - position)
  2345. {
  2346. }
  2347. public int EffectiveLength
  2348. {
  2349. get
  2350. {
  2351. return End - Begin;
  2352. }
  2353. }
  2354. public int Begin
  2355. {
  2356. get
  2357. {
  2358. return Math.Max (Position, 0);
  2359. }
  2360. }
  2361. public int End
  2362. {
  2363. get
  2364. {
  2365. return Math.Min (Position + Length, SafeValue.Length);
  2366. }
  2367. }
  2368. string SafeValue
  2369. {
  2370. get
  2371. {
  2372. return Value ?? Strings.Empty;
  2373. }
  2374. }
  2375. public bool Equals (SubString other)
  2376. {
  2377. var value = SafeValue;
  2378. var otherValue = other.SafeValue;
  2379. var effectiveLength = EffectiveLength;
  2380. var effectiveOtherLength = other.EffectiveLength;
  2381. if (effectiveLength != effectiveOtherLength)
  2382. {
  2383. return false;
  2384. }
  2385. var begin = Begin;
  2386. var otherBegin = other.Begin;
  2387. var end = End;
  2388. var otherEnd = other.End;
  2389. var diff = otherBegin - begin;
  2390. for (var iter = begin; iter < end; ++iter)
  2391. {
  2392. if (value[iter] != otherValue[iter + diff])
  2393. {
  2394. return false;
  2395. }
  2396. }
  2397. return true;
  2398. }
  2399. public override string ToString ()
  2400. {
  2401. return SafeValue.Substring (Begin, EffectiveLength);
  2402. }
  2403. public char this[int index]
  2404. {
  2405. get
  2406. {
  2407. var realIndex = Position + index;
  2408. return realIndex > -1 && realIndex < Value.Length
  2409. ? Value[Position + index]
  2410. : ' '
  2411. ;
  2412. }
  2413. }
  2414. public static bool operator == (SubString left, SubString right)
  2415. {
  2416. return left.Equals (right);
  2417. }
  2418. public static bool operator != (SubString left, SubString right)
  2419. {
  2420. return !(left == right);
  2421. }
  2422. public override bool Equals (object obj)
  2423. {
  2424. return obj is SubString && Equals ((SubString) obj);
  2425. }
  2426. public override int GetHashCode ()
  2427. {
  2428. var result = 0x55555555;
  2429. var value = SafeValue;
  2430. var end = End;
  2431. for (var iter = Begin; iter < end; ++iter)
  2432. {
  2433. result = (result * 397) ^ value[iter];
  2434. }
  2435. return result;
  2436. }
  2437. }
  2438. }
  2439. }
  2440. namespace Include
  2441. {
  2442. // ----------------------------------------------------------------------------------------------
  2443. // Copyright (c) Mårten Rånge.
  2444. // ----------------------------------------------------------------------------------------------
  2445. // This source code is subject to terms and conditions of the Microsoft Public License. A
  2446. // copy of the license can be found in the License.html file at the root of this distribution.
  2447. // If you cannot locate the Microsoft Public License, please send an email to
  2448. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  2449. // by the terms of the Microsoft Public License.
  2450. // ----------------------------------------------------------------------------------------------
  2451. // You must not remove this notice, or any other, from this software.
  2452. // ----------------------------------------------------------------------------------------------
  2453. namespace MicroParser
  2454. {
  2455. #if MICRO_PARSER_NET35
  2456. static partial class Tuple
  2457. {
  2458. public static Tuple<TValue1, TValue2> Create<TValue1, TValue2> (
  2459. TValue1 value1
  2460. , TValue2 value2
  2461. )
  2462. {
  2463. return new Tuple<TValue1, TValue2>
  2464. {
  2465. Item1 = value1 ,
  2466. Item2 = value2 ,
  2467. };
  2468. }
  2469. public static Tuple<TValue1, TValue2, TValue3> Create<TValue1, TValue2, TValue3> (
  2470. TValue1 value1
  2471. , TValue2 value2
  2472. , TValue3 value3
  2473. )
  2474. {
  2475. return new Tuple<TValue1, TValue2, TValue3>
  2476. {
  2477. Item1 = value1 ,
  2478. Item2 = value2 ,
  2479. Item3 = value3 ,
  2480. };
  2481. }
  2482. }
  2483. partial struct Tuple<TValue1, TValue2>
  2484. {
  2485. public TValue1 Item1;
  2486. public TValue2 Item2;
  2487. #if !MICRO_PARSER_SUPPRESS_ANONYMOUS_TYPE
  2488. public override string ToString ()
  2489. {
  2490. return new
  2491. {
  2492. Item1,
  2493. Item2,
  2494. }.ToString ();
  2495. }
  2496. #endif
  2497. }
  2498. partial struct Tuple<TValue1, TValue2, TValue3>
  2499. {
  2500. public TValue1 Item1;
  2501. public TValue2 Item2;
  2502. public TValue3 Item3;
  2503. #if !MICRO_PARSER_SUPPRESS_ANONYMOUS_TYPE
  2504. public override string ToString ()
  2505. {
  2506. return new
  2507. {
  2508. Item1,
  2509. Item2,
  2510. Item3,
  2511. }.ToString ();
  2512. }
  2513. #endif
  2514. }
  2515. #endif
  2516. }
  2517. }
  2518. // ----------------------------------------------------------------------------------------------
  2519. // Copyright (c) Mårten Rånge.
  2520. // ----------------------------------------------------------------------------------------------
  2521. // This source code is subject to terms and conditions of the Microsoft Public License. A
  2522. // copy of the license can be found in the License.html file at the root of this distribution.
  2523. // If you cannot locate the Microsoft Public License, please send an email to
  2524. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  2525. // by the terms of the Microsoft Public License.
  2526. // ----------------------------------------------------------------------------------------------
  2527. // You must not remove this notice, or any other, from this software.
  2528. // ----------------------------------------------------------------------------------------------
  2529. namespace MicroParser.Json
  2530. {
  2531. using System;
  2532. using System.Collections;
  2533. using System.Collections.Generic;
  2534. using System.Diagnostics;
  2535. using System.Globalization;
  2536. using System.Linq;
  2537. using System.Text;
  2538. using Include.MicroParser;
  2539. public sealed partial class JsonUnserializeError
  2540. {
  2541. public readonly string ErrorMessage;
  2542. public readonly int ErrorOffset;
  2543. public JsonUnserializeError (string errorMessage, int errorOffset)
  2544. {
  2545. ErrorMessage = errorMessage ?? "<NULL>";
  2546. ErrorOffset = errorOffset;
  2547. }
  2548. public override string ToString ()
  2549. {
  2550. return new
  2551. {
  2552. ErrorOffset,
  2553. ErrorMessage
  2554. }.ToString ();
  2555. }
  2556. }
  2557. static partial class JsonSerializer
  2558. {
  2559. static partial void TransformObjects (object[] objects, ref object result);
  2560. static partial void TransformObject (Tuple<string, object>[] properties, ref object result);
  2561. #if MICRO_PARSER_JSON_NET35
  2562. static IEnumerable<TZipped> Zip<T0, T1, TZipped>(
  2563. this IEnumerable<T0> values0,
  2564. IEnumerable<T1> values1,
  2565. Func<T0, T1, TZipped> zipper
  2566. )
  2567. {
  2568. if (zipper == null)
  2569. {
  2570. throw new ArgumentNullException ("zipper");
  2571. }
  2572. values0 = values0 ?? new T0[0];
  2573. values1 = values1 ?? new T1[0];
  2574. using (var e0 = values0.GetEnumerator ())
  2575. using (var e1 = values1.GetEnumerator ())
  2576. {
  2577. bool moveNext0;
  2578. bool moveNext1;
  2579. while ((moveNext0 = e0.MoveNext () & (moveNext1 = e1.MoveNext ())))
  2580. {
  2581. yield return zipper (e0.Current, e1.Current);
  2582. }
  2583. if (moveNext0 != moveNext1)
  2584. {
  2585. throw new ArgumentException ("values0 and values1 must be of same length");
  2586. }
  2587. }
  2588. }
  2589. #endif
  2590. static readonly Parser<object> s_parser;
  2591. struct StringPart
  2592. {
  2593. readonly int m_item1;
  2594. readonly int m_item2;
  2595. public StringPart (int position, int length)
  2596. {
  2597. m_item1 = position;
  2598. m_item2 = length;
  2599. }
  2600. public StringPart (char ch)
  2601. {
  2602. m_item1 = ch;
  2603. m_item2 = 0;
  2604. }
  2605. public bool IsRange
  2606. {
  2607. get
  2608. {
  2609. return m_item2 > 0;
  2610. }
  2611. }
  2612. public int Position
  2613. {
  2614. get
  2615. {
  2616. Debug.Assert (IsRange);
  2617. return m_item1;
  2618. }
  2619. }
  2620. public int Length
  2621. {
  2622. get
  2623. {
  2624. Debug.Assert (IsRange);
  2625. return m_item2;
  2626. }
  2627. }
  2628. public char Character
  2629. {
  2630. get
  2631. {
  2632. unchecked
  2633. {
  2634. Debug.Assert (!IsRange);
  2635. return (char)(m_item1 & 0xFFFF);
  2636. }
  2637. }
  2638. }
  2639. }
  2640. static Parser<string> CombineStringParts (
  2641. this Parser<StringPart[]> parser
  2642. )
  2643. {
  2644. Parser<string>.Function function =
  2645. state =>
  2646. {
  2647. var result = parser.Execute (state);
  2648. if (result.State.HasError ())
  2649. {
  2650. return result.Failure<string>();
  2651. }
  2652. var text = state.Text;
  2653. var length = 0;
  2654. foreach (var stringPart in result.Value)
  2655. {
  2656. if (stringPart.IsRange)
  2657. {
  2658. length += stringPart.Length;
  2659. }
  2660. else
  2661. {
  2662. ++length;
  2663. }
  2664. }
  2665. var charArray = new char[length];
  2666. var position = 0;
  2667. foreach (var stringPart in result.Value)
  2668. {
  2669. if (stringPart.IsRange)
  2670. {
  2671. var begin = stringPart.Position;
  2672. var end = begin + stringPart.Length;
  2673. for (var iter = begin; iter < end; ++iter)
  2674. {
  2675. charArray[position++] = text[iter];
  2676. }
  2677. }
  2678. else
  2679. {
  2680. charArray[position++] = stringPart.Character;
  2681. }
  2682. }
  2683. var stringValue = new string (charArray);
  2684. return result.Success (stringValue);
  2685. };
  2686. return function;
  2687. }
  2688. static object TransformObjects (object[] objects)
  2689. {
  2690. object result = objects;
  2691. TransformObjects (objects, ref result);
  2692. return result;
  2693. }
  2694. static object TransformObject (Tuple<string, object>[] properties)
  2695. {
  2696. object result = properties;
  2697. TransformObject (properties, ref result);
  2698. return result;
  2699. }
  2700. static JsonSerializer ()
  2701. {
  2702. // Language spec at www.json.org
  2703. // ReSharper disable InconsistentNaming
  2704. Func<char, Parser<Empty>> p_char = CharParser.SkipChar;
  2705. Func<string, Parser<Empty>> p_str = CharParser.SkipString;
  2706. var p_spaces = CharParser.SkipWhiteSpace ();
  2707. const string expected_bool = "bool" ;
  2708. const string expected_string = "string" ;
  2709. const string expected_number = "number" ;
  2710. const string expected_null = "null" ;
  2711. var p_null = p_str ("null").Map (null as object);
  2712. var p_true = p_str ("true").Map (true as object);
  2713. var p_false = p_str ("false").Map (false as object);
  2714. var p_number = CharParser.Double ().Map (d => d as object);
  2715. const string simpleEscape = "\"\\/bfnrt";
  2716. const string simpleEscapeMap = "\"\\/\b\f\n\r\t";
  2717. Debug.Assert (simpleEscape.Length == simpleEscapeMap.Length);
  2718. var simpleSwitchCases = simpleEscape
  2719. .Zip (
  2720. simpleEscapeMap,
  2721. (l, r) => Parser.Case (l.ToString (s_cultureInfo), Parser.Return (new StringPart (r)))
  2722. );
  2723. var otherSwitchCases =
  2724. new[]
  2725. {
  2726. Parser.Case (
  2727. "u",
  2728. CharParser
  2729. .Hex (minCount: 4, maxCount: 4)
  2730. .Map (ui => new StringPart ((char) ui)))
  2731. };
  2732. var switchCases = simpleSwitchCases.Concat (otherSwitchCases).ToArray ();
  2733. var p_escape = Parser.Switch (
  2734. Parser.SwitchCharacterBehavior.Consume,
  2735. switchCases
  2736. );
  2737. var p_string = Parser
  2738. .Choice (
  2739. CharParser.NoneOf ("\\\"", minCount: 1).Map (ss => new StringPart (ss.Position, ss.Length)),
  2740. CharParser.SkipChar ('\\').KeepRight (p_escape))
  2741. .Many ()
  2742. .Between (
  2743. p_char ('"'),
  2744. p_char ('"')
  2745. )
  2746. .CombineStringParts ();
  2747. var p_array_redirect = Parser.Redirect<object>();
  2748. var p_object_redirect = Parser.Redirect<object>();
  2749. var p_array = p_array_redirect.Parser;
  2750. var p_object = p_object_redirect.Parser;
  2751. // .Switch is used as we can tell by looking at the first character which parser to use
  2752. var p_value = Parser
  2753. .Switch (
  2754. Parser.SwitchCharacterBehavior.Leave,
  2755. Parser.Case ("\"" , p_string.Map (v => v as object), expected_string ),
  2756. Parser.Case ("-0123456789" , p_number , expected_number ),
  2757. Parser.Case ("{" , p_object ),
  2758. Parser.Case ("[" , p_array ),
  2759. Parser.Case ("t" , p_true , expected_bool ),
  2760. Parser.Case ("f" , p_false , expected_bool ),
  2761. Parser.Case ("n" , p_null , expected_null )
  2762. )
  2763. .KeepLeft (p_spaces);
  2764. var p_elements = p_value
  2765. .Array (p_char (',')
  2766. .KeepLeft (p_spaces))
  2767. .Map (TransformObjects);
  2768. p_array_redirect.ParserRedirect = p_elements
  2769. .Between (
  2770. p_char ('[').KeepLeft (p_spaces),
  2771. p_char (']')
  2772. );
  2773. var p_member = Parser
  2774. .Group (
  2775. p_string.KeepLeft (p_spaces),
  2776. p_char (':').KeepLeft (p_spaces).KeepRight (p_value)
  2777. );
  2778. var p_members = p_member
  2779. .Array (p_char (',')
  2780. .KeepLeft (p_spaces));
  2781. p_object_redirect.ParserRedirect = p_members
  2782. .Between (
  2783. p_char ('{').KeepLeft (p_spaces),
  2784. p_char ('}')
  2785. )
  2786. .Map (TransformObject);
  2787. var p_eos = Parser.EndOfStream ();
  2788. // .Switch is used as we can tell by looking at the first character which parser to use
  2789. var p_root = Parser
  2790. .Switch (
  2791. Parser.SwitchCharacterBehavior.Leave,
  2792. Parser.Case ("{", p_object),
  2793. Parser.Case ("[", p_array)
  2794. )
  2795. .KeepLeft (p_spaces);
  2796. s_parser = p_spaces.KeepRight (p_root).KeepLeft (p_spaces).KeepLeft (p_eos);
  2797. // ReSharper restore InconsistentNaming
  2798. }
  2799. public static object Unserialize (string str)
  2800. {
  2801. var result = Parser.Parse (s_parser, str);
  2802. return result.IsSuccessful ? result.Value : new JsonUnserializeError (result.ErrorMessage, result.Unconsumed.Begin);
  2803. }
  2804. static readonly CultureInfo s_cultureInfo = CultureInfo.InvariantCulture;
  2805. static void SerializeImpl (StringBuilder stringBuilder, object dyn)
  2806. {
  2807. if (dyn is double)
  2808. {
  2809. stringBuilder.Append (((double)dyn).ToString (s_cultureInfo));
  2810. }
  2811. else if (dyn is int)
  2812. {
  2813. stringBuilder.Append (((int)dyn).ToString (s_cultureInfo));
  2814. }
  2815. else if (dyn is string)
  2816. {
  2817. SerializeStringValue (stringBuilder, (string)dyn);
  2818. }
  2819. else if (dyn is bool)
  2820. {
  2821. if ((bool)dyn)
  2822. {
  2823. stringBuilder.Append ("true");
  2824. }
  2825. else
  2826. {
  2827. stringBuilder.Append ("false");
  2828. }
  2829. }
  2830. else if (dyn is IDictionary<string, object>)
  2831. {
  2832. var dictionary = dyn as IDictionary<string, object>;
  2833. stringBuilder.Append ('{');
  2834. var first = true;
  2835. foreach (var kv in dictionary)
  2836. {
  2837. if (first)
  2838. {
  2839. first = false;
  2840. }
  2841. else
  2842. {
  2843. stringBuilder.Append (',');
  2844. }
  2845. SerializeStringValue (stringBuilder, kv.Key);
  2846. stringBuilder.Append (':');
  2847. SerializeImpl (stringBuilder, kv.Value);
  2848. }
  2849. stringBuilder.Append ('}');
  2850. }
  2851. else if (dyn is IEnumerable)
  2852. {
  2853. var enumerable = (IEnumerable)dyn;
  2854. stringBuilder.Append ('[');
  2855. var first = true;
  2856. foreach (var obj in enumerable)
  2857. {
  2858. if (first)
  2859. {
  2860. first = false;
  2861. }
  2862. else
  2863. {
  2864. stringBuilder.Append (',');
  2865. }
  2866. SerializeImpl (stringBuilder, obj);
  2867. }
  2868. stringBuilder.Append (']');
  2869. }
  2870. else
  2871. {
  2872. stringBuilder.Append ("null");
  2873. }
  2874. }
  2875. static void SerializeStringValue (StringBuilder stringBuilder, string str)
  2876. {
  2877. stringBuilder.Append ('"');
  2878. foreach (var ch in str)
  2879. {
  2880. switch (ch)
  2881. {
  2882. case '\b':
  2883. stringBuilder.Append ("\\b");
  2884. break;
  2885. case '\f':
  2886. stringBuilder.Append ("\\f");
  2887. break;
  2888. case '\n':
  2889. stringBuilder.Append ("\\n");
  2890. break;
  2891. case '\r':
  2892. stringBuilder.Append ("\\r");
  2893. break;
  2894. case '\t':
  2895. stringBuilder.Append ("\\t");
  2896. break;
  2897. default:
  2898. stringBuilder.Append (ch);
  2899. break;
  2900. }
  2901. }
  2902. stringBuilder.Append ('"');
  2903. }
  2904. public static string Serialize (object dyn)
  2905. {
  2906. var sb = new StringBuilder (32);
  2907. SerializeImpl (sb, dyn);
  2908. return sb.ToString ();
  2909. }
  2910. }
  2911. }
  2912. // ----------------------------------------------------------------------------------------------
  2913. // Copyright (c) Mårten Rånge.
  2914. // ----------------------------------------------------------------------------------------------
  2915. // This source code is subject to terms and conditions of the Microsoft Public License. A
  2916. // copy of the license can be found in the License.html file at the root of this distribution.
  2917. // If you cannot locate the Microsoft Public License, please send an email to
  2918. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  2919. // by the terms of the Microsoft Public License.
  2920. // ----------------------------------------------------------------------------------------------
  2921. // You must not remove this notice, or any other, from this software.
  2922. // ----------------------------------------------------------------------------------------------
  2923. #if MICRO_PARSER_JSON_MAKE_PUBLIC
  2924. namespace MicroParser.Json
  2925. {
  2926. public partial class JsonUnserializeError
  2927. {
  2928. }
  2929. public partial class JsonSerializer
  2930. {
  2931. }
  2932. }
  2933. #endif
  2934. // ----------------------------------------------------------------------------------------------
  2935. // Copyright (c) Mårten Rånge.
  2936. // ----------------------------------------------------------------------------------------------
  2937. // This source code is subject to terms and conditions of the Microsoft Public License. A
  2938. // copy of the license can be found in the License.html file at the root of this distribution.
  2939. // If you cannot locate the Microsoft Public License, please send an email to
  2940. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  2941. // by the terms of the Microsoft Public License.
  2942. // ----------------------------------------------------------------------------------------------
  2943. // You must not remove this notice, or any other, from this software.
  2944. // ----------------------------------------------------------------------------------------------
  2945. #if MICRO_PARSER_JSON_EXPANDO_OBJECT
  2946. namespace MicroParser.Json
  2947. {
  2948. using System;
  2949. using System.Collections.Generic;
  2950. using System.Dynamic;
  2951. partial class JsonSerializer
  2952. {
  2953. static partial void TransformObject (Tuple<string, object>[] properties, ref object result)
  2954. {
  2955. IDictionary<string, object> expando = new ExpandoObject ();
  2956. foreach (var p in properties)
  2957. {
  2958. expando[p.Item1 ?? ""] = p.Item2;
  2959. }
  2960. result = expando;
  2961. }
  2962. }
  2963. }
  2964. #endif