aboutsummaryrefslogtreecommitdiff
path: root/src/parser
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2022-01-13 21:20:23 +0530
committerAkshay Nair <phenax5@gmail.com>2022-01-13 21:20:23 +0530
commit016821207f1f2294dd09935a4c1d14d78ff3aed1 (patch)
treef5f852cb94be77ceb5a97a0b6d62cb323090b00b /src/parser
parente26086fef3cf142cffd145836a4c7c12cfeb9656 (diff)
downloadelxr-016821207f1f2294dd09935a4c1d14d78ff3aed1.tar.gz
elxr-016821207f1f2294dd09935a4c1d14d78ff3aed1.zip
refactor(parser): reimplements alt parser
Diffstat (limited to 'src/parser')
-rw-r--r--src/parser/index.ts40
-rw-r--r--src/parser/utils.ts17
2 files changed, 30 insertions, 27 deletions
diff --git a/src/parser/index.ts b/src/parser/index.ts
index e815334..1f9da13 100644
--- a/src/parser/index.ts
+++ b/src/parser/index.ts
@@ -1,5 +1,5 @@
import { flow, pipe } from 'fp-ts/function'
-import { chain, left, orElse, right } from 'fp-ts/lib/Either'
+import { chain, map as mapE, left, orElse, right } from 'fp-ts/lib/Either'
import {
delimited,
digits,
@@ -15,6 +15,7 @@ import {
ParserResult,
prefixed,
satifyChar,
+ sepBy1,
suffixed,
symbol,
tuple3,
@@ -22,7 +23,7 @@ import {
} from './utils'
import { Expr, ListExpr, Literal } from '../types'
import {getOrElse, map} from 'fp-ts/lib/Option'
-import {snd} from 'fp-ts/lib/Tuple'
+import {mapFst, snd} from 'fp-ts/lib/Tuple'
const start = mapTo(symbol('^'), _ => Expr.Start())
const end = mapTo(symbol('$'), _ => Expr.End())
@@ -47,17 +48,6 @@ const wrapQuantifiers: (e: ParserResult<Expr>) => ParserResult<Expr> = chain(
),
)
-const wrapAlt: (e: ParserResult<Expr>) => ParserResult<Expr> = chain(
- ([expr, input]) =>
- pipe(
- input,
- mapTo(prefixed(symbol('|'), many1(expressionP)), rest =>
- Expr.Or({ left: expr, right: rest }),
- ),
- orElse(_ => right([expr, input])),
- ),
-)
-
const propRegex = /^[A-Za-z0-9_-]$/
export const propertyName: Parser<string> = pipe(
@@ -76,7 +66,7 @@ const objectProperty = (input: string) =>
pair(propertyName, many0(expressionP)),
symbol(']'),
),
- ([name, exprs]) => Expr.PropertyMatch({ name, expr: Expr.Group({ exprs }) }),
+ ([name, exprs]) => Expr.PropertyMatch({ name, expr: exprsToGroup(exprs) }),
),
)
@@ -111,13 +101,17 @@ const literalP: Parser<Literal> = delimited(
whitespaces0,
)
-const expressionP: Parser<Expr> = (input: string) =>
+const expressionP: Parser<Expr> = (input: string) => pipe(
+ input,
+ sepBy1(symbol('|'), groupP),
+ mapE(mapFst(exprs => exprs.length === 1 ? exprs[0] : Expr.Or({ exprs }))),
+)
+
+const atomP: Parser<Expr> = (input: string) =>
pipe(
input,
or([
- mapTo(delimited(symbol('('), many1(expressionP), symbol(')')), exprs =>
- Expr.Group({ exprs }),
- ),
+ mapTo(delimited(symbol('('), many1(expressionP), symbol(')')), exprsToGroup),
objectProperty,
nextItem,
anyItem,
@@ -129,21 +123,21 @@ const expressionP: Parser<Expr> = (input: string) =>
mapTo(literalP, Expr.Literal),
]),
wrapQuantifiers,
- wrapAlt,
+ //wrapAlt,
)
+const exprsToGroup = (exprs: Expr[]) => exprs.length === 1 ? exprs[0] : Expr.Group({ exprs })
+const groupP: Parser<Expr> = mapTo(many1(atomP), exprsToGroup)
+
export const parser: Parser<ListExpr> = tuple3(
optional(start),
- many1(expressionP),
+ expressionP,
optional(end),
)
/*
-
{3,6} => 3 to 6 instances
(> 5) => number greater than
(< 5) => number less than
-[name x] => apply x on property `name`
/x/ => match regular expression (string values in list)
-
*/
diff --git a/src/parser/utils.ts b/src/parser/utils.ts
index 908405e..cee1de7 100644
--- a/src/parser/utils.ts
+++ b/src/parser/utils.ts
@@ -1,4 +1,4 @@
-import { constant, flow, pipe } from 'fp-ts/function'
+import { flow, pipe } from 'fp-ts/function'
import {
Either,
left,
@@ -9,9 +9,10 @@ import {
fold,
orElseW,
} from 'fp-ts/Either'
-import { none, some, Option } from 'fp-ts/Option'
+import { none, some, Option, getOrElse } from 'fp-ts/Option'
import { fst, mapFst, mapSnd, snd } from 'fp-ts/Tuple'
import { eq } from '../utils'
+import { prepend } from 'fp-ts/lib/Array'
export type char = string
@@ -25,11 +26,19 @@ export const constP =
(inp: string) =>
right([v, inp])
+export const sepBy1 = <T>(sep: Parser<any>, parser: Parser<T>): Parser<T[]> =>
+ flow(
+ parser,
+ chain(([val, nextInput]) =>
+ pipe(nextInput, many0(prefixed(sep, parser)), map(mapFst(prepend(val)))),
+ ),
+ )
+
export const many0 = <T>(parser: Parser<T>): Parser<Array<T>> =>
flow(
parser,
chain(([a, nextInput]) =>
- pipe(nextInput, many0(parser), map(mapFst(ls => [a, ...ls]))),
+ pipe(nextInput, many0(parser), map(mapFst(prepend(a)))),
),
orElse(
flow(
@@ -134,7 +143,7 @@ export const andThen =
export const optional = <T>(p: Parser<T>): Parser<Option<T>> =>
flow(
- p,
+ recoverInput(p),
fold(
flow(
mapFst(_ => none),