PageRenderTime 55ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/JsonVisualizer/Internal/IncludeMicroParser.Json.cs

#
C# | 3485 lines | 2662 code | 521 blank | 302 comment | 174 complexity | 8d37ca31b129a7bc9d59f00c4aac4129 MD5 | raw file

Large files files are truncated, but you can click here to view the full 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. errorMe

Large files files are truncated, but you can click here to view the full file