Skip to content

Commit

Permalink
feat(combinators/many1): add many1 combinator
Browse files Browse the repository at this point in the history
  • Loading branch information
norskeld committed May 14, 2022
1 parent 11d42b4 commit 5342135
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
23 changes: 22 additions & 1 deletion src/combinators/many.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export function many<T>(parser: Parser<T>): Parser<Array<T>> {
return {
isOk: true,
pos: nextPos,
input,
value: values
}
}
Expand All @@ -29,3 +28,25 @@ export function many<T>(parser: Parser<T>): Parser<Array<T>> {
}
}
}

export function many1<T>(parser: Parser<T>): Parser<Array<T>> {
return {
parse(input, pos) {
const result = many(parser).parse(input, pos)

switch (result.isOk && result.value.length > 0) {
case true: {
return result
}

case false: {
return {
isOk: false,
pos: result.pos,
expected: 'at least one successful application of the parser'
}
}
}
}
}
}
18 changes: 16 additions & 2 deletions tests/combinators/many.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { many } from '@lib/combinators/many'
import { many, many1 } from '@lib/combinators/many'
import { string } from '@lib/parsers/string'

import { run, result, should } from '@tests/@helpers'
import { run, result, should, testFailure } from '@tests/@helpers'

describe(many, () => {
it('should succeed with an array of matched strings', () => {
Expand All @@ -20,3 +20,17 @@ describe(many, () => {
should.matchState(actual, expected)
})
})

describe(many1, () => {
it('should succeed with an array of matched strings', () => {
const parser = many1(string('x!'))
const actual = run(parser, 'x!x!x!')
const expected = result(true, ['x!', 'x!', 'x!'])

should.matchState(actual, expected)
})

it('should fail if nothing matched', () => {
testFailure('y!y!y!', () => many1(string('x!')))
})
})

0 comments on commit 5342135

Please sign in to comment.