diff options
| author | Akshay Nair <phenax5@gmail.com> | 2022-01-07 18:13:40 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2022-01-07 18:14:06 +0530 |
| commit | 6639605b395ceb1355c95e06ff0e1470adc54101 (patch) | |
| tree | 01e300c50086f8db47300388ab3d7a5e5f83072d /src/parser/index.ts | |
| parent | b3fc08cae05f997e71d846109d400e630b8a4c35 (diff) | |
| download | elxr-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.ts | 81 |
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) + +*/ |
