aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2022-01-13 23:05:10 +0530
committerAkshay Nair <phenax5@gmail.com>2022-01-13 23:05:10 +0530
commit11bb9b17ad84e0c07aaa50ce65411a8adf692685 (patch)
treebba6dcdbbec45e75d6451081be0171c5f5ce3619
parentba94e799aa352c2fd472b694c745388e3e9feee8 (diff)
downloadelxr-11bb9b17ad84e0c07aaa50ce65411a8adf692685.tar.gz
elxr-11bb9b17ad84e0c07aaa50ce65411a8adf692685.zip
feat(parser): adds sequence parser
-rw-r--r--src/parser/index.ts17
-rw-r--r--src/types.ts2
-rw-r--r--tests/parser.spec.ts39
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(),
+ ],
+ }),
+ ),
+ )
+ })
})