Don't consume the end pattern multiple times in script pattern

This commit is contained in:
Tangent Wantwight 2023-08-25 16:44:50 -04:00
parent 9ce7ec2598
commit e538471611
2 changed files with 24 additions and 3 deletions

View file

@ -1,5 +1,14 @@
import { escapeHtml } from "./helpers";
import { AtLeast, Choose, End, Pattern, Regex, Sequence, Use } from "./peg";
import {
AtLeast,
Choose,
End,
Pattern,
Peek,
Regex,
Sequence,
Use,
} from "./peg";
import {
Script,
Word as WordType,
@ -105,10 +114,12 @@ function scriptTmpl(bareWordCharRegex: RegExp, endPattern: Pattern<unknown>) {
Choose(
PreWordWhitespace.map(() => []),
CommandTerminator.map(() => []),
Sequence(Comment, Choose(CommandTerminator, endPattern)).map(() => []),
Sequence(Comment, Choose(CommandTerminator, Peek(endPattern))).map(
() => []
),
Sequence(
commandTmpl(bareWordCharRegex),
Choose(CommandTerminator, endPattern)
Choose(CommandTerminator, Peek(endPattern))
).map(([words]) => words)
)
),

View file

@ -182,6 +182,16 @@ export function AtLeast<T>(min: number, pattern: Pattern<T>): Pattern<T[]> {
}).expects(pattern.expectLabel);
}
/**
* Creates a pattern that matches the given pattern, but consumes no input.
*/
export function Peek<T>(pattern: Pattern<T>): Pattern<T> {
return WrapPattern(function (source, index) {
const [value, furthest, expected] = pattern(source, index);
return [value ? [value[0], index] : null, furthest, expected];
}).expects(pattern.expectLabel);
}
/**
* Creates a pattern that matches the end of input
*/