aboutsummaryrefslogtreecommitdiff
path: root/src/parser/index.ts
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2022-01-07 18:13:40 +0530
committerAkshay Nair <phenax5@gmail.com>2022-01-07 18:14:06 +0530
commit6639605b395ceb1355c95e06ff0e1470adc54101 (patch)
tree01e300c50086f8db47300388ab3d7a5e5f83072d /src/parser/index.ts
parentb3fc08cae05f997e71d846109d400e630b8a4c35 (diff)
downloadelxr-6639605b395ceb1355c95e06ff0e1470adc54101.tar.gz
elxr-6639605b395ceb1355c95e06ff0e1470adc54101.zip
refactor: simplifies quantifier logic + moves stuff around
Diffstat (limited to 'src/parser/index.ts')
-rw-r--r--src/parser/index.ts81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/parser/index.ts b/src/parser/index.ts
new file mode 100644
index 0000000..f522214
--- /dev/null
+++ b/src/parser/index.ts
@@ -0,0 +1,81 @@
+import { constant, pipe } from 'fp-ts/function'
+import { chain, orElse, right } from 'fp-ts/lib/Either'
+import {
+ delimited,
+ many1,
+ mapTo,
+ optional,
+ or,
+ Parser,
+ ParserResult,
+ symbol,
+ tuple3,
+} from './utils'
+import { Expr } from '../types'
+
+export const start = mapTo(symbol('^'), constant({ tag: 'Start' } as Expr))
+export const end = mapTo(symbol('$'), constant({ tag: 'End' } as Expr))
+export const anyItem = mapTo(symbol('.'), constant({ tag: 'AnyItem' } as Expr))
+export const nextItem = mapTo(
+ symbol(','),
+ constant({ tag: 'NextItem' } as Expr)
+)
+export const anyString = mapTo(
+ symbol('\\s'),
+ constant({ tag: 'AnyString' } as Expr)
+)
+export const anyNumber = mapTo(
+ symbol('\\n'),
+ constant({ tag: 'AnyNumber' } as Expr)
+)
+export const anyBool = mapTo(
+ symbol('\\b'),
+ constant({ tag: 'AnyBool' } as Expr)
+)
+export const truthy = mapTo(symbol('\\T'), constant({ tag: 'Truthy' } as Expr))
+export const falsey = mapTo(symbol('\\F'), constant({ tag: 'Falsey' } as Expr))
+
+export const wrapQuantifiers: (e: ParserResult<Expr>) => ParserResult<Expr> =
+ chain(([expr, input]) =>
+ pipe(
+ input,
+ or([
+ mapTo(symbol('*'), (_) => ({ tag: 'ZeroOrMore', expr } as Expr)),
+ mapTo(symbol('+'), (_) => ({ tag: 'OneOrMore', expr } as Expr)),
+ mapTo(symbol('?'), (_) => ({ tag: 'Optional', expr } as Expr)),
+ ]),
+ orElse(() => right([expr, input]))
+ )
+ )
+
+export const expressionP: Parser<Expr> = (input: string) =>
+ pipe(
+ input,
+ or([
+ mapTo(
+ delimited(symbol('('), many1(expressionP), symbol(')')),
+ (exprs) => ({ tag: 'Group', exprs } as Expr)
+ ),
+ nextItem,
+ anyItem,
+ anyString,
+ anyNumber,
+ anyBool,
+ truthy,
+ falsey,
+ ]),
+ wrapQuantifiers
+ )
+
+export const parser = tuple3(optional(start), many1(expressionP), optional(end))
+
+/*
+
+{3,6} => 3 to 6 instances
+(> 5) => number greater than
+(< 5) => number less than
+[name x] => apply x on property `name`
+| => or
+/x/ => match regular expression (string values in list)
+
+*/