diff options
| author | Akshay Nair <phenax5@gmail.com> | 2022-01-13 23:05:10 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2022-01-13 23:05:10 +0530 |
| commit | 11bb9b17ad84e0c07aaa50ce65411a8adf692685 (patch) | |
| tree | bba6dcdbbec45e75d6451081be0171c5f5ce3619 | |
| parent | ba94e799aa352c2fd472b694c745388e3e9feee8 (diff) | |
| download | elxr-11bb9b17ad84e0c07aaa50ce65411a8adf692685.tar.gz elxr-11bb9b17ad84e0c07aaa50ce65411a8adf692685.zip | |
feat(parser): adds sequence parser
| -rw-r--r-- | src/parser/index.ts | 17 | ||||
| -rw-r--r-- | src/types.ts | 2 | ||||
| -rw-r--r-- | tests/parser.spec.ts | 39 |
3 files changed, 42 insertions, 16 deletions
diff --git a/src/parser/index.ts b/src/parser/index.ts index 1f9da13..50f2786 100644 --- a/src/parser/index.ts +++ b/src/parser/index.ts @@ -28,7 +28,6 @@ import {mapFst, snd} from 'fp-ts/lib/Tuple' const start = mapTo(symbol('^'), _ => Expr.Start()) const end = mapTo(symbol('$'), _ => Expr.End()) const anyItem = mapTo(symbol('.'), _ => Expr.AnyItem()) -const nextItem = mapTo(symbol(','), _ => Expr.NextItem()) const anyString = mapTo(symbol('\\s'), _ => Expr.AnyString()) const anyNumber = mapTo(symbol('\\n'), _ => Expr.AnyNumber()) const anyBool = mapTo(symbol('\\b'), _ => Expr.AnyBool()) @@ -101,19 +100,26 @@ const literalP: Parser<Literal> = delimited( whitespaces0, ) -const expressionP: Parser<Expr> = (input: string) => pipe( +const infixOp = (op: Parser<any>): Parser<Expr[]> => (input: string) => pipe( input, - sepBy1(symbol('|'), groupP), - mapE(mapFst(exprs => exprs.length === 1 ? exprs[0] : Expr.Or({ exprs }))), + sepBy1(op, groupP), + chain(([exprs, nextInput]) => exprs.length === 1 + ? left(['Infix operator parsing error', input]) + : right([exprs, nextInput])), ) +const altP: Parser<Expr> = mapTo(infixOp(symbol('|')), exprs => Expr.Or({ exprs })) + +const sequenceP: Parser<Expr> = mapTo(infixOp(symbol(',')), exprs => Expr.Sequence({ exprs })) + +const expressionP: Parser<Expr> = (input: string) => or([ altP, sequenceP, groupP ])(input) + const atomP: Parser<Expr> = (input: string) => pipe( input, or([ mapTo(delimited(symbol('('), many1(expressionP), symbol(')')), exprsToGroup), objectProperty, - nextItem, anyItem, anyString, anyNumber, @@ -123,7 +129,6 @@ const atomP: Parser<Expr> = (input: string) => mapTo(literalP, Expr.Literal), ]), wrapQuantifiers, - //wrapAlt, ) const exprsToGroup = (exprs: Expr[]) => exprs.length === 1 ? exprs[0] : Expr.Group({ exprs }) diff --git a/src/types.ts b/src/types.ts index bc30453..ea9f9bf 100644 --- a/src/types.ts +++ b/src/types.ts @@ -26,7 +26,7 @@ export type Expr = Union<{ Group: { exprs: Expr[] }, PropertyMatch: { name: string, expr: Expr }, Literal: Literal, - NextItem: _, + Sequence: { exprs: Expr[] }, }> export const Expr = constructors<Expr>() diff --git a/tests/parser.spec.ts b/tests/parser.spec.ts index 510e5bb..6c773d6 100644 --- a/tests/parser.spec.ts +++ b/tests/parser.spec.ts @@ -11,13 +11,11 @@ import { parser } from '../src/parser' import { none, some } from 'fp-ts/Option' import { Expr, Literal } from '../src/types' import { jlog } from '../src/utils' +import { parse } from 'fp-ts/lib/Json' -const wrap = (e: Expr) => - right([[none, e, none], '']) -const grouped = (l: Expr[]) => - wrap(Expr.Group({ exprs: l })) -const groupedAlt = (l: Expr[]) => - wrap(Expr.Or({ exprs: l })) +const wrap = (e: Expr) => right([[none, e, none], '']) +const grouped = (l: Expr[]) => wrap(Expr.Group({ exprs: l })) +const groupedAlt = (l: Expr[]) => wrap(Expr.Or({ exprs: l })) describe('Parser', () => { it('should do shit', () => { @@ -84,6 +82,17 @@ describe('Parser', () => { Expr.AnyNumber(), ]), ) + expect(parser(/ ((\s|\b\T)|\n) /.source)).toEqual( + groupedAlt([ + Expr.Or({ + exprs: [ + Expr.AnyString(), + Expr.Group({ exprs: [Expr.AnyBool(), Expr.Truthy()] }), + ] + }), + Expr.AnyNumber(), + ]), + ) }) it('object proprtyu', () => { @@ -106,9 +115,7 @@ describe('Parser', () => { expect(parser(/ 0.105 /.source)).toEqual( wrap(Expr.Literal(Literal.Number(0.105))), ) - expect(parser(/ 9 /.source)).toEqual( - wrap(Expr.Literal(Literal.Number(9))), - ) + expect(parser(/ 9 /.source)).toEqual(wrap(Expr.Literal(Literal.Number(9)))) expect(parser(/ 23 /.source)).toEqual( wrap(Expr.Literal(Literal.Number(23))), ) @@ -135,4 +142,18 @@ describe('Parser', () => { wrap(Expr.Literal(Literal.Boolean(false))), ) }) + + it('sequence of values', () => { + expect(parser(/true, \s\T, \n/.source)).toEqual( + wrap( + Expr.Sequence({ + exprs: [ + Expr.Literal(Literal.Boolean(true)), + Expr.Group({ exprs: [Expr.AnyString(), Expr.Truthy()] }), + Expr.AnyNumber(), + ], + }), + ), + ) + }) }) |
