@mattwca/little-parser-lib 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/parsers/parsers.ts +12 -2
package/package.json
CHANGED
package/src/parsers/parsers.ts
CHANGED
|
@@ -92,8 +92,8 @@ export function or<T>(...parsers: ParseFn<T>[]): ParseFn<T> {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
/**
|
|
95
|
-
* Applies a parser repeatedly until it fails
|
|
96
|
-
* If the parser fails on the first attempt, returns a failure.
|
|
95
|
+
* Applies a parser repeatedly until it fails or doesn't make progress (move the position), collecting
|
|
96
|
+
* all successful results into an array. If the parser fails on the first attempt, returns a failure.
|
|
97
97
|
*/
|
|
98
98
|
export function many(parser: ParseFn<any>): ParseFn<any> {
|
|
99
99
|
return (tokenStream: TokenStream) => {
|
|
@@ -102,10 +102,20 @@ export function many(parser: ParseFn<any>): ParseFn<any> {
|
|
|
102
102
|
let parseFailure = null;
|
|
103
103
|
|
|
104
104
|
while (true) {
|
|
105
|
+
const positionBefore = tokenStream.position;
|
|
105
106
|
tokenStream.storePosition();
|
|
106
107
|
|
|
107
108
|
const result = parser(tokenStream);
|
|
109
|
+
|
|
108
110
|
if (isSuccessfulResult(result)) {
|
|
111
|
+
const positionAfter = tokenStream.position;
|
|
112
|
+
|
|
113
|
+
// Check if the parser made any progress - if it didn't, we break out to avoid infinite loops.
|
|
114
|
+
if (positionAfter === positionBefore) {
|
|
115
|
+
tokenStream.restorePosition();
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
|
|
109
119
|
results.push(result.result);
|
|
110
120
|
tokenStream.clearPosition();
|
|
111
121
|
} else {
|