From d4303f0d8e9b485ec54a59aa54c8bd353f10b70e Mon Sep 17 00:00:00 2001 From: maestrow Date: Sun, 23 May 2021 17:15:44 +0300 Subject: [PATCH] 1st LR working example --- src/cli.ts | 39 ++++++++++++++++++++++----------------- src/parser.ts | 30 +++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/src/cli.ts b/src/cli.ts index 5557936..4761f69 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,11 +1,9 @@ import * as fs from "fs"; import { IMatchResult, Parser } from './parser' -import { Ast } from './grammar-ast' -import { math1 } from './grammars/math1' -import { ometa1, proj } from './grammars/ometa1' import { TraceDiscovery } from "./utils/trace-discover"; import { IParserFn } from "types"; import * as equal from "fast-deep-equal/es6"; +import { Ast } from "grammar-ast"; const printTrace = (p: Parser, input) => { const disco = new TraceDiscovery(p.grammar, input, p.trace.data) @@ -26,20 +24,27 @@ const printRes = (p: Parser, res: IMatchResult) => { // console.dir(trace, {depth:1}) } -const input = fs.readFileSync('src/grammars/ometa1.ometa', 'utf-8') -const p = new Parser(ometa1, proj) -const r = p.match(input as unknown as any[], 'ometa') - -saveTrace(p, input) +type Expr = + | ['lr', Ast.Expr] +type Grammar = Ast.Grammar + +const g: Grammar = [ + ['expr', ['lr', ['alt', [ + ['seq', [ + ['rule', 'expr'], + ['equal', '+'], + ['rule', 'num'], + ]], + ['rule', 'num'] + ]]]], + ['num', ['range', '0', '9']] +] + +const input = "1+2+3" +const p = new Parser(g) +const r = p.match(input as unknown as any[], 'expr') + +// saveTrace(p, input) printRes(p, r) -const isEqual = equal(ometa1, r.result) - -console.log('\nDiff:\n') -console.log('isEqual: ' + isEqual) - -fs.writeFileSync("./dist/diff_expected.json", JSON.stringify(ometa1, null, 2)) -fs.writeFileSync("./dist/diff_actual.json", JSON.stringify(r.result, null, 2)) - - diff --git a/src/parser.ts b/src/parser.ts index b664f05..8da2a62 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -15,6 +15,8 @@ export interface IMatchResult { result?: any } +let counter = 0 +let memo: IParseResult export class Parser implements Ast.IParser { protected state: State @@ -64,7 +66,7 @@ export class Parser implements Ast.IParser { // ToDo: translate Если ф-ция парсера вызывает другую ф-цию парсера, то успешный результат вложенного парсера нельзя пробрасывать наверх. // Иначе может произойти двойной консум - @Memoize((...args) => JSON.stringify(args)) + //@Memoize((...args) => JSON.stringify(args)) expr (e: Ast.GenericExpr): IParserFn { const combinator = this[e[0]] if (typeof(combinator) !== 'function') { @@ -91,6 +93,32 @@ export class Parser implements Ast.IParser { return () => this.project(name, e)() } + lr = (expr: Ast.GenericExpr) => { + const p = this.expr(expr) + + return () => { + console.log(counter, memo) + if (counter === 0) { + counter++ + let res = p() + memo = res + console.log(memo) + while (res.success) { + res = p() + if (res.success) + memo = res + } + return memo + } else if (counter === 1) { + counter++ + return this.fail() + } else { + counter++ + return memo + } + } + } + empty = (): IParserFn => () => { return this.success() }