combinators.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*
  2. * Copyright (C) 2024 Puter Technologies Inc.
  3. *
  4. * This file is part of Phoenix Shell.
  5. *
  6. * Phoenix Shell is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License as published
  8. * by the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Affero General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Affero General Public License
  17. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. import { ParserConfigDSL } from "../dsl/ParserBuilder.js";
  20. import { AcceptParserUtil, Parser, ParseResult } from "../parse.js";
  21. export class SequenceParserImpl {
  22. static createFunction ({ parserFactory }) {
  23. return (...parsers) => {
  24. const conf = new ParserConfigDSL(parserFactory, this);
  25. conf.parseParams({ parsers });
  26. return conf;
  27. };
  28. }
  29. constructor ({ parsers }) {
  30. this.parsers = parsers.map(AcceptParserUtil.adapt);
  31. }
  32. parse (lexer) {
  33. const results = [];
  34. for ( const parser of this.parsers ) {
  35. const subLexer = lexer.fork();
  36. const result = parser.parse(subLexer);
  37. if ( result.status === ParseResult.UNRECOGNIZED ) {
  38. return;
  39. }
  40. if ( result.status === ParseResult.INVALID ) {
  41. // TODO: this is wrong
  42. return { done: true, value: result };
  43. }
  44. lexer.join(subLexer);
  45. results.push(result.value);
  46. }
  47. return { $: 'sequence', results };
  48. }
  49. }
  50. export class ChoiceParserImpl {
  51. static createFunction ({ parserFactory }) {
  52. return (...parsers) => {
  53. const conf = new ParserConfigDSL(parserFactory, this);
  54. conf.parseParams({ parsers });
  55. return conf;
  56. };
  57. }
  58. constructor ({ parsers }) {
  59. this.parsers = parsers.map(AcceptParserUtil.adapt);
  60. }
  61. parse (lexer) {
  62. for ( const parser of this.parsers ) {
  63. const subLexer = lexer.fork();
  64. const result = parser.parse(subLexer);
  65. if ( result.status === ParseResult.UNRECOGNIZED ) {
  66. continue;
  67. }
  68. if ( result.status === ParseResult.INVALID ) {
  69. // TODO: this is wrong
  70. return { done: true, value: result };
  71. }
  72. lexer.join(subLexer);
  73. return result.value;
  74. }
  75. return;
  76. }
  77. }
  78. export class RepeatParserImpl {
  79. static createFunction ({ parserFactory }) {
  80. return (delegate) => {
  81. const conf = new ParserConfigDSL(parserFactory, this);
  82. conf.parseParams({ delegate });
  83. return conf;
  84. };
  85. }
  86. constructor ({ delegate }) {
  87. delegate = AcceptParserUtil.adapt(delegate);
  88. this.delegate = delegate;
  89. }
  90. parse (lexer) {
  91. const results = [];
  92. for ( ;; ) {
  93. const subLexer = lexer.fork();
  94. const result = this.delegate.parse(subLexer);
  95. if ( result.status === ParseResult.UNRECOGNIZED ) {
  96. break;
  97. }
  98. if ( result.status === ParseResult.INVALID ) {
  99. return { done: true, value: result };
  100. }
  101. lexer.join(subLexer);
  102. results.push(result.value);
  103. }
  104. return { $: 'repeat', results };
  105. }
  106. }
  107. export class NoneParserImpl {
  108. static createFunction ({ parserFactory }) {
  109. return () => {
  110. const conf = new ParserConfigDSL(parserFactory, this);
  111. return conf;
  112. };
  113. }
  114. parse () {
  115. return { $: 'none', $discard: true };
  116. }
  117. }