You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

GrammarRule.cs 2.7 kB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. using System;
  2. using System.Collections.Generic;
  3. using LLama.Exceptions;
  4. using LLama.Native;
  5. namespace LLama.Grammars
  6. {
  7. /// <summary>
  8. /// A single rule in a <see cref="Grammar"/>
  9. /// </summary>
  10. public sealed record GrammarRule
  11. {
  12. /// <summary>
  13. /// Name of this rule
  14. /// </summary>
  15. public string Name { get; }
  16. /// <summary>
  17. /// The elements of this grammar rule
  18. /// </summary>
  19. public IReadOnlyList<LLamaGrammarElement> Elements { get; }
  20. /// <summary>
  21. /// Create a new GrammarRule containing the given elements
  22. /// </summary>
  23. /// <param name="name"></param>
  24. /// <param name="elements"></param>
  25. /// <exception cref="ArgumentException"></exception>
  26. public GrammarRule(string name, IReadOnlyList<LLamaGrammarElement> elements)
  27. {
  28. Validate(elements, name);
  29. Name = name;
  30. Elements = elements;
  31. }
  32. private static void Validate(IReadOnlyList<LLamaGrammarElement> elements, string name)
  33. {
  34. if (elements.Count == 0)
  35. throw new ArgumentException("Cannot create a GrammarRule with zero elements", nameof(elements));
  36. if (elements[elements.Count - 1].Type != LLamaGrammarElementType.END)
  37. throw new ArgumentException("Last grammar element must be END", nameof(elements));
  38. for (var i = 0; i < elements.Count; i++)
  39. {
  40. switch (elements[i].Type)
  41. {
  42. case LLamaGrammarElementType.END:
  43. if (i != elements.Count - 1)
  44. throw new GrammarUnexpectedEndElement(name, i);
  45. continue;
  46. case LLamaGrammarElementType.CHAR_RNG_UPPER:
  47. if (i == 0 || !elements[i - 1].IsCharElement())
  48. throw new GrammarUnexpectedCharRngElement(name, i);
  49. break;
  50. case LLamaGrammarElementType.CHAR_ALT:
  51. if (i == 0 || !elements[i - 1].IsCharElement())
  52. throw new GrammarUnexpectedCharAltElement(name, i);
  53. break;
  54. case LLamaGrammarElementType.ALT:
  55. case LLamaGrammarElementType.RULE_REF:
  56. case LLamaGrammarElementType.CHAR:
  57. case LLamaGrammarElementType.CHAR_NOT:
  58. break;
  59. default:
  60. throw new ArgumentException($"Unknown grammar element type: '{elements[i].Type}'", nameof(elements));
  61. }
  62. }
  63. }
  64. }
  65. }