1. my class Grammar is Match {
  2. method parse(\target, :$rule, :$args, Mu :$actions, :$filename) is raw {
  3. my $*LINEPOSCACHE;
  4. nqp::stmts(
  5. (my $grammar := self.new(:orig(target), |%_).set_actions($actions)),
  6. nqp::decont(nqp::getlexcaller('$/') =
  7. nqp::if(
  8. (my $cursor := nqp::if(
  9. $rule,
  10. nqp::if(
  11. $args,
  12. $grammar."$rule"(|$args.Capture),
  13. $grammar."$rule"()
  14. ),
  15. nqp::if(
  16. $args,
  17. $grammar.TOP(|$args.Capture),
  18. $grammar.TOP()
  19. ),
  20. )),
  21. nqp::stmts(
  22. (my $match := $cursor.MATCH),
  23. nqp::while(
  24. $match && nqp::isne_i(
  25. nqp::getattr_i(($match := $cursor.MATCH),Match,'$!pos'),
  26. target.chars
  27. ),
  28. $match := ($cursor := $cursor.'!cursor_next'()).MATCH
  29. ),
  30. $match || Nil
  31. ),
  32. Nil
  33. )
  34. )
  35. )
  36. }
  37. method subparse(\target, :$rule, :$args, :$actions) is raw {
  38. nqp::stmts(
  39. (my $grammar := self.new(:orig(target), |%_).set_actions($actions)),
  40. nqp::decont(nqp::getlexcaller('$/') =
  41. nqp::if(
  42. $rule,
  43. nqp::if(
  44. $args,
  45. $grammar."$rule"(|$args.Capture).MATCH,
  46. $grammar."$rule"().MATCH,
  47. ),
  48. nqp::if(
  49. $args,
  50. $grammar.TOP(|$args.Capture).MATCH,
  51. $grammar.TOP().MATCH
  52. ),
  53. )
  54. )
  55. )
  56. }
  57. method parsefile(Str(Cool) $filename, :$enc) is raw {
  58. nqp::decont(nqp::getlexcaller('$/') = nqp::if(
  59. nqp::elems(nqp::getattr(%_,Map,'$!storage')),
  60. self.parse($filename.IO.slurp(:$enc), :$filename, |%_),
  61. self.parse($filename.IO.slurp(:$enc), :$filename)
  62. ))
  63. }
  64. }