diff --git a/integration-ts/examples/beginner/chars.ts b/integration-ts/examples/beginner/chars.ts index 15a15cb..798cba9 100644 --- a/integration-ts/examples/beginner/chars.ts +++ b/integration-ts/examples/beginner/chars.ts @@ -9,7 +9,7 @@ const stream = Streams.ofString('abc'); const charsParser = C.char('a') .then(C.char('b')) .then(C.char('c')) - .then(F.eos.drop()); // End Of Stream ; droping its value, just checking it's here + .then(F.eos().drop()); // End Of Stream ; droping its value, just checking it's here let charsParsing = charsParser.parse(stream); assertEquals('abc', charsParsing.value.join(''), 'Chars parsing'); diff --git a/integration-ts/examples/beginner/floor.ts b/integration-ts/examples/beginner/floor.ts index b857e5c..db6305c 100644 --- a/integration-ts/examples/beginner/floor.ts +++ b/integration-ts/examples/beginner/floor.ts @@ -8,7 +8,7 @@ import {Streams, F, C, N} from '@robusta/trash' let stream= Streams.ofString('|4.6|'); const floorCombinator = C.char('|').drop() - .then(N.numberLiteral) // we have ['|',4.6], we keep 4.6 + .then(N.numberLiteral()) // we have ['|',4.6], we keep 4.6 .then(C.char('|').drop()) // we have [4.6, '|'], we keep 4.6 .map(x =>Math.floor(x)); diff --git a/integration-ts/examples/beginner/hello-something.ts b/integration-ts/examples/beginner/hello-something.ts index ad4e11d..97e5ff6 100644 --- a/integration-ts/examples/beginner/hello-something.ts +++ b/integration-ts/examples/beginner/hello-something.ts @@ -6,7 +6,7 @@ import {assertEquals, assertArrayEquals, assertTrue} from '../../assert'; const helloParser = C.string("Hello") .then(C.char(' ').rep()) .then(C.char("'")).drop() - .then(C.letter.rep()) // keeping repeated ascii letters + .then(C.letter().rep()) // keeping repeated ascii letters .then(C.char("'").drop()); // keeping previous letters const parsing = helloParser.parse(Streams.ofString("Hello 'World'")); diff --git a/integration-ts/examples/beginner/number.ts b/integration-ts/examples/beginner/number.ts index ba52a49..794c0be 100644 --- a/integration-ts/examples/beginner/number.ts +++ b/integration-ts/examples/beginner/number.ts @@ -8,7 +8,7 @@ const s = Streams.ofString(document); // numberLitteral defines any int or float number // We expect a number, then eos: End Of Stream // We use drop() because we don't need the value of F.eos, we only want 12 -const numberParser = N.numberLiteral.then(F.eos.drop()); +const numberParser = N.numberLiteral.then(F.eos().drop()); const parsing = numberParser.parse(s); // If the parser reached the end of stream (F.eos) without rejection, parsing is accepted diff --git a/integration-ts/examples/flow/nop-any-eos.ts b/integration-ts/examples/flow/nop-any-eos.ts new file mode 100644 index 0000000..47d7e73 --- /dev/null +++ b/integration-ts/examples/flow/nop-any-eos.ts @@ -0,0 +1,25 @@ +import {Streams, F, C,Option, N, SingleParser} from '@robusta/trash' +import {assertFalse, assertTrue} from '../../assert'; + +function day() { + return C.stringIn(['MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY']); +} + +function a(){ + return C.char('a'); +} + +const string = '-MONDAY-'; + + + +function combinator() { + return F.any().then(day()).then(F.nop()).then(F.any()).then(F.eos()); +} + +let stream = Streams.ofString(string); +let parsing = combinator().parse(stream); + +assertTrue(parsing.isAccepted()); +assertTrue(parsing.isConsumed()); + diff --git a/integration-ts/examples/index.ts b/integration-ts/examples/index.ts index dc81a01..b55963d 100644 --- a/integration-ts/examples/index.ts +++ b/integration-ts/examples/index.ts @@ -1,11 +1,11 @@ import './beginner/chars' -import './beginner/floor' +//import './beginner/floor' import './beginner/hello-something' -import './beginner/number' +//import './beginner/number' import './beginner/response' import './flow/try-with-no-or' import './flow/not' +import './flow/nop-any-eos' import './lazy/transmission' - diff --git a/integration-ts/package.json b/integration-ts/package.json index 3078fa8..123fcbc 100644 --- a/integration-ts/package.json +++ b/integration-ts/package.json @@ -4,7 +4,7 @@ "description": "used to test npm publications", "main": "index.js", "dependencies": { - "@robusta/trash": "0.0.3", + "@robusta/trash": "0.0.4", "axios": "^0.16.2" }, "devDependencies": { diff --git a/masala-parser.d.ts b/masala-parser.d.ts index 8bb4eb2..a1d260b 100644 --- a/masala-parser.d.ts +++ b/masala-parser.d.ts @@ -1,8 +1,6 @@ /** * Written by Nicolas Zozol - * Inspired by https://github.com/jon-hanson/parsecj */ - export interface Unit {} // Not needed @@ -35,7 +33,8 @@ export interface Try { export interface List { size: number; isEmpty: boolean; - array: Array + array(): Array + join(string:string): string; } @@ -75,6 +74,7 @@ export interface VoidResponseextends Response { export interface Response { isAccepted(): boolean + isConsumed(): boolean fold(accept, reject?): Response; map(f): Response; flatMap(f): Response; @@ -88,26 +88,39 @@ export interface ArrayParser extends IParser { then(p: SingleParser): ArrayParser; then(p: VoidParser): ArrayParser; map (f: (T) => Y): ArrayParser; - flatMap (f: () => Z): ArrayParser; filter(f: (T) => boolean): ArrayParser + opt():ArrayParser>; + or>(p: P): ArrayParser|P; } /* List with same values ; need bo call array() */ -export interface ListParser { - parse(stream: Stream, index?: number): Response>; +export interface ListParser extends IParser{ + parse(stream: Stream, index?: number): ListResponse; then(p: SingleParser): ArrayParser; + then(p: VoidParser): ListParser; + map (f: (T) => Y): ListParser; + opt():ListParser>; + // + or>(p: P): ListParser|P; } -interface SingleParser extends IParser { +export interface SingleParser extends IParser { parse(stream: Stream, index?: number): SingleResponse; then(p: SingleParser): ArrayParser; + then(p: ListParser): ListParser; then(p: VoidParser): SingleParser; map (f: (T) => Y): SingleParser; + + opt():SingleParser>; //filter(f: () => boolean): SingleParser + or>(p: P): SingleParser|P; } interface VoidParser extends IParser { - then(p: IParser): SingleParser; + then(p: SingleParser): SingleParser< Y>; + then(p: ListParser): ListParser; + opt():VoidParser; + or>(p: P): VoidParser|P; } /** @@ -117,14 +130,18 @@ export interface IParser { // Needed because opt() won(t know if we have void, array or single //then(p: IParser): IParser; map (f: (T) => Y): IParser; + flatMap>( builder:parserBuilder ):P; drop(): VoidParser; + rep(): ListParser; + thenReturns(obj:Y):SingleParser; + debug(s:string, b?:boolean); + //then(p: IParser): IParser; + /*flatMap (f: () => Y): IParser; filter(f: (T) => boolean): IParser match(value: T): IParser; thenReturns(value: Y): SingleParser; - or(p: IParser): IParser; opt(): IParser; - rep(): ListParser>; occurrence(n: number): ListParser; optrep(): IParser>; chain(): IParser; @@ -132,40 +149,56 @@ export interface IParser { */ // parse(stream: Stream, index?: number): Response; } - -export declare class Parser implements IParser { - then(p: IParser): IParser; - flatMap(f: () => Y): IParser ; - map(f: (T: any) => Y): IParser; - filter(f: (T: any) => boolean): IParser ; - match(value: T): IParser ; - drop(): VoidParser ; - thenReturns(value: Y): SingleParser ; - or(p: IParser): IParser ; - opt(): IParser ; - rep(): ListParser> ; - occurrence(n: number): ListParser ; - optrep(): IParser> ; - chain(): IParser ; - debug(hint?: string, details?: boolean): IParser; - parse(stream: Stream, index?: number): Response ; -} +/* + export declare class Parser implements IParser { + + then(p: IParser): IParser; + flatMap(f: () => Y): IParser ; + map(f: (T: any) => Y): IParser; + filter(f: (T: any) => boolean): IParser ; + match(value: T): IParser ; + drop(): VoidParser ; + thenReturns(value: Y): SingleParser ; + or(p: IParser): IParser ; + opt(): IParser ; + rep(): ListParser> ; + occurrence(n: number): ListParser ; + optrep(): IParser> ; + chain(): IParser ; + debug(hint?: string, details?: boolean): IParser; + parse(stream: Stream, index?: number): Response ; + }*/ export interface Response { + isCompleted(): boolean isAccepted(): boolean fold(accept, reject?): Response; map(f): Response; flatMap(f): Response; filter(f: (value) => boolean): Response; + offset: number; } interface CharBundle { - char(string): SingleParser; + char(string:string): SingleParser; + string(string:string): SingleParser; + stringIn(strings:string[]): SingleParser; + letter: SingleParser; } +export type parserBuilder> = (...rest:any[])=>P; + +type extension> = T; + interface FlowBundle { - nop: () => void; - eos: SingleParser; + parse>(P):P; + nop(): VoidParser; + try>(parser:P):P; + any():SingleParser; + subStream(length:number):ListParser + lazy> (builder: parserBuilder, args:any[]): P; + not>(P):SingleParser; + eos(): SingleParser; } interface NumberBundle { diff --git a/package.json b/package.json index 6926986..49d6026 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@robusta/trash", "description": "Masala Parser", "license": "LGPL-2.1", - "version": "0.0.3", + "version": "0.0.4", "keywords": [ "parser", "javascript",