Skip to content

Commit

Permalink
refactor: restructure & rename combinators/parsers
Browse files Browse the repository at this point in the history
Simplified the structure and renamed combinators/parsers to match the conventions of libraries like parsec or parser-combinators (Haskell), and purescript-parsing (PureScript).

BREAKING CHANGE:

- Lifted contents of the `internal` directory since the library itself gets bundled anyway.
- Removed all aliases for parsers and combinators.
- Removed `whitespaceOptional` parser. Its functionality can be replicated with `optional(whitespace())`.
- Renamed the following parsers:
  - `newline` -> `eol`
  - `integer` -> `int`
  - `integerUnsigned` -> `uint`
  - `uniString` -> `ustring`
- Renamed the following combinators:
  - `list` -> `sepBy`
  • Loading branch information
norskeld committed Jan 23, 2022
1 parent 74333ef commit f6a6956
Show file tree
Hide file tree
Showing 58 changed files with 164 additions and 249 deletions.
18 changes: 9 additions & 9 deletions src/combinators.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
export * from './internal/combinators/chain'
export * from './internal/combinators/choice'
export * from './internal/combinators/error'
export * from './internal/combinators/list'
export * from './internal/combinators/many'
export * from './internal/combinators/map'
export * from './internal/combinators/optional'
export * from './internal/combinators/sequence'
export * from './internal/combinators/take'
export * from './combinators/chain'
export * from './combinators/choice'
export * from './combinators/error'
export * from './combinators/many'
export * from './combinators/map'
export * from './combinators/optional'
export * from './combinators/sepBy'
export * from './combinators/sequence'
export * from './combinators/take'
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,3 @@ export function choice<T>(...ps: Array<Parser<T>>): Parser<T> {
}
}
}

export { choice as alt }
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,3 @@ import { choice } from './choice'
export function optional<T>(parser: Parser<T>): Parser<T | null> {
return choice(parser, nothing())
}

export { optional as opt }
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ function toList<T, S>([list, pair]: [T, Array<[S, T]>]): Array<T> {
return [list].concat(pair.map(([, value]: [S, T]) => value))
}

export function list<T, S>(parser: Parser<T>, sep: Parser<S>): Parser<Array<T>> {
export function sepBy<T, S>(parser: Parser<T>, sep: Parser<S>): Parser<Array<T>> {
return map(sequence(parser, many(sequence(sep, parser))), toList)
}

export { list as sepBy }
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,3 @@ export function sequence<T>(...ps: Array<Parser<T>>): Parser<Array<T>> {
}
}
}

export { sequence as seq }
2 changes: 0 additions & 2 deletions src/internal/combinators/take.ts → src/combinators/take.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,3 @@ export function takeSides<T1, T2, T3>(
): Parser<[T1, T3]> {
return map(sequence(p1, p2, p3), toSides)
}

export { takeLeft as tleft, takeMid as tmid, takeRight as tright, takeSides as tsides }
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './internal/state'
export * from './state'
16 changes: 0 additions & 16 deletions src/internal/parsers/whitespace.ts

This file was deleted.

23 changes: 12 additions & 11 deletions src/parsers.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
export * from './internal/parsers/defer'
export * from './internal/parsers/eof'
export * from './internal/parsers/float'
export * from './internal/parsers/integer'
export * from './internal/parsers/letter'
export * from './internal/parsers/newline'
export * from './internal/parsers/nothing'
export * from './internal/parsers/regexp'
export * from './internal/parsers/rest'
export * from './internal/parsers/string'
export * from './internal/parsers/whitespace'
export * from './parsers/defer'
export * from './parsers/eof'
export * from './parsers/eol'
export * from './parsers/float'
export * from './parsers/integer'
export * from './parsers/letter'
export * from './parsers/nothing'
export * from './parsers/regexp'
export * from './parsers/rest'
export * from './parsers/run'
export * from './parsers/string'
export * from './parsers/whitespace'
File renamed without changes.
File renamed without changes.
6 changes: 2 additions & 4 deletions src/internal/parsers/newline.ts → src/parsers/eol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import { string } from './string'
const EOL_UNIX = '\n'
const EOL_NON_UNIX = '\r\n'

export function newline(): Parser<string> {
return error(choice(string(EOL_UNIX), string(EOL_NON_UNIX)), 'newline')
export function eol(): Parser<string> {
return error(choice(string(EOL_UNIX), string(EOL_NON_UNIX)), 'end of line')
}

export { newline as eol }
File renamed without changes.
6 changes: 2 additions & 4 deletions src/internal/parsers/integer.ts → src/parsers/integer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,10 @@ function createIntegerParser(re: RegExp, expectation: string, radix: number) {
}
}

export function integer(radix = 10): Parser<number> {
export function int(radix = 10): Parser<number> {
return createIntegerParser(INT_SIGNED_RE, 'signed integer', radix)
}

export function integerUnsigned(radix = 10): Parser<number> {
export function uint(radix = 10): Parser<number> {
return createIntegerParser(INT_UNSIGNED_RE, 'unsigned integer', radix)
}

export { integer as int, integerUnsigned as uint }
File renamed without changes.
File renamed without changes.
2 changes: 0 additions & 2 deletions src/internal/parsers/regexp.ts → src/parsers/regexp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,3 @@ export function regexp(re: RegExp, expected: string): Parser<string> {
}
}
}

export { regexp as re }
File renamed without changes.
File renamed without changes.
6 changes: 2 additions & 4 deletions src/internal/parsers/string.ts → src/parsers/string.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { success, failure, State, Parser } from '../state'
import { size } from '../unicode'
import { size } from '../utils/unicode'

export function string(match: string): Parser<string> {
return {
Expand All @@ -20,7 +20,7 @@ export function string(match: string): Parser<string> {
}
}

export function uniString(match: string): Parser<string> {
export function ustring(match: string): Parser<string> {
return {
parse(state: State) {
const index = state.index + size(match)
Expand All @@ -38,5 +38,3 @@ export function uniString(match: string): Parser<string> {
}
}
}

export { string as str, uniString as ustr }
9 changes: 9 additions & 0 deletions src/parsers/whitespace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Parser } from '../state'

import { regexp } from './regexp'

const WHITESPACE_REQUIRED_RE = /\s+/g

export function whitespace(): Parser<string> {
return regexp(WHITESPACE_REQUIRED_RE, 'whitespace')
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions tests/@helpers/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Parser, Result } from '@lib/internal/state'
import { run as internal$run } from '@lib/internal/parsers/run'
import { run as internal$run } from '@lib/parsers/run'
import { Parser, Result } from '@lib/state'

type ResultKind = 'success' | 'failure'

Expand Down
12 changes: 2 additions & 10 deletions tests/combinators.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,21 @@ import * as exposed from '@lib/combinators'

import { should } from '@tests/@helpers'

it(`should expose combinators`, () => {
it('should expose combinators', () => {
should.expose(
exposed,
'chainl',
'choice',
'alt',
'error',
'list',
'sepBy',
'many',
'map',
'mapTo',
'optional',
'opt',
'sequence',
'seq',
'takeLeft',
'tleft',
'takeMid',
'tmid',
'takeRight',
'tright',
'takeSides',
'tsides'
'takeSides'
)
})
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { chainl } from '@lib/internal/combinators/chain'
import { map } from '@lib/internal/combinators/map'
import { regexp } from '@lib/internal/parsers/regexp'
import { string } from '@lib/internal/parsers/string'
import { takeRight } from '@lib/internal/combinators/take'
import { takeRight } from '@lib/combinators/take'
import { chainl } from '@lib/combinators/chain'
import { regexp } from '@lib/parsers/regexp'
import { string } from '@lib/parsers/string'
import { map } from '@lib/combinators/map'

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

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { choice } from '@lib/internal/combinators/choice'
import { string } from '@lib/internal/parsers/string'
import { choice } from '@lib/combinators/choice'
import { string } from '@lib/parsers/string'

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

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { error } from '@lib/internal/combinators/error'
import { string } from '@lib/internal/parsers/string'
import { error } from '@lib/combinators/error'
import { string } from '@lib/parsers/string'

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

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { many } from '@lib/internal/combinators/many'
import { string } from '@lib/internal/parsers/string'
import { many } from '@lib/combinators/many'
import { string } from '@lib/parsers/string'

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

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { map, mapTo } from '@lib/internal/combinators/map'
import { string } from '@lib/internal/parsers/string'
import { map, mapTo } from '@lib/combinators/map'
import { string } from '@lib/parsers/string'

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

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { optional } from '@lib/internal/combinators/optional'
import { sequence } from '@lib/internal/combinators/sequence'
import { string } from '@lib/internal/parsers/string'
import { optional } from '@lib/combinators/optional'
import { sequence } from '@lib/combinators/sequence'
import { string } from '@lib/parsers/string'

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

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { list } from '@lib/internal/combinators/list'
import { string } from '@lib/internal/parsers/string'
import { sepBy } from '@lib/combinators/sepBy'
import { string } from '@lib/parsers/string'

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

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

should.matchState(actual, expected)
})

it('should fail with the value of the first failed parser', () => {
const parser = list(string('hello'), string('?'))
const parser = sepBy(string('hello'), string('?'))
const actual = run(parser, 'bye?bye?')
const expected = result('failure', 'hello')

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { sequence } from '@lib/internal/combinators/sequence'
import { string } from '@lib/internal/parsers/string'
import { sequence } from '@lib/combinators/sequence'
import { string } from '@lib/parsers/string'

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

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { takeLeft, takeMid, takeRight, takeSides } from '@lib/internal/combinators/take'
import { string } from '@lib/internal/parsers/string'
import { takeLeft, takeMid, takeRight, takeSides } from '@lib/combinators/take'
import { string } from '@lib/parsers/string'

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

// TODO: Add failing cases.
describe(takeLeft, () => {
it('should succeed with the value of the left parser ', () => {
it('should succeed with the value of the parser on the left-hand side', () => {
const parser = takeLeft(string('left'), string('mid'))
const actual = run(parser, 'leftmid')
const expected = result('success', 'left')
Expand All @@ -16,7 +16,7 @@ describe(takeLeft, () => {

// TODO: Add failing cases.
describe(takeMid, () => {
it('should succeed with the value of the middle parser', () => {
it('should succeed with the value of the parser in the middle', () => {
const parser = takeMid(string('left'), string('mid'), string('right'))
const actual = run(parser, 'leftmidright')
const expected = result('success', 'mid')
Expand All @@ -27,7 +27,7 @@ describe(takeMid, () => {

// TODO: Add failing cases.
describe(takeRight, () => {
it('should succeed with the value of the middle parser', () => {
it('should succeed with the value of the parser on right-hand side', () => {
const parser = takeRight(string('mid'), string('right'))
const actual = run(parser, 'midright')
const expected = result('success', 'right')
Expand Down
4 changes: 0 additions & 4 deletions tests/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,3 @@ import { should } from '@tests/@helpers'
it('should expose state helpers', () => {
should.expose(exposed, 'success', 'failure')
})

it('should expose runner', () => {
should.expose(exposed, 'run')
})
Loading

0 comments on commit f6a6956

Please sign in to comment.