From c3125a863f92194ebd751aee7a178b10ebf97a6d Mon Sep 17 00:00:00 2001 From: MaximeBarniaudy Date: Tue, 11 Jun 2024 13:52:48 +0900 Subject: [PATCH] Move side effect of variable assignment in namespace out of grammar for logic and ease of use reasons --- grammar_parser.meta | 110 +++++++++++++++++++++++++++----------------- rawgrammar.leg | 6 +-- 2 files changed, 72 insertions(+), 44 deletions(-) diff --git a/grammar_parser.meta b/grammar_parser.meta index b39bcbe..faed0e7 100644 --- a/grammar_parser.meta +++ b/grammar_parser.meta @@ -361,18 +361,22 @@ Grammar = Object.subtype(#Grammar); Grammar.addRulesFromNamespace(namespace) { for (key in __namespaces__[namespace].keys()) { if (key == #__nsname__) continue; - self[key] = Closure.new( - environment: nil, - function: Lambda.new( - parameters: [#stream, #context, #actions], - body: __namespaces__[namespace][key].getMatchingExpression().body, - name: key, - parent: self - ) - ) + self.addRule(key, __namespaces__[namespace][key]); } } +Grammar.addRule(ruleName, rule) { + self[ruleName] = Closure.new( + environment: nil, + function: Lambda.new( + parameters: [#stream, #context, #actions], + body: rule.getMatchingExpression().body, + name: ruleName, + parent: self + ) + ) +} + //global functionCounts = []; // //increaseCount(function) { @@ -641,11 +645,16 @@ with(#HardCodedPeg); grammar = Sequence.new() .push(RuleCall.new(name: #ws)) - .push(Plus.new(expression: Sequence.new() - .push(Assignment.new(name: #d, rule: RuleCall.new(name: #definition))) - .push(Action.new(parseTree: `{ __namespaces__.last()[d.name] = d.expression; })) - )) - .push(RuleCall.new(name: #end_of_file)); + .push(Alternation.new() + .push(Sequence.new() + .push(Assignment.new(name: #d, rule: RuleCall.new(name: #definition))) + .push(Action.new(parseTree: `{ d; })) + ) + .push(Sequence.new() + .push(RuleCall.new(name: #end_of_file)) + .push(Action.new(parseTree: `{ nil; })) + ) + ); definition = Sequence.new() @@ -943,15 +952,20 @@ global stream = newStream(readfile("rawminproto.leg")); global context = Context.new(outerContext: nil).init(); global actions = []; -global match = HardCodedPeg.grammar(stream, context, actions); -print("Matching rawminproto.leg : ", match, "\n"); -if (!match) exit(); +while(!stream.atEnd()) { + HardCodedPeg.grammar(stream, context, actions); + + with(#metaLanguage); + local definition = { for (actionAndContext in actions) { + actionAndContext.action.execute(actionAndContext.context); + } }; + if (definition == nil) continue; // end of file case + setInTopNamespace(definition.name, definition.expression); + without(#metaLanguage); -with(#metaLanguage); -for (actionAndContext in actions) { - actionAndContext.action.execute(actionAndContext.context); + global actions = []; } -without(#metaLanguage); + println("\n--------- META ---------\n\n"); println(__namespaces__.metaLanguage); @@ -959,17 +973,19 @@ global stream = newStream(readfile("rawgrammar.leg")); global context = Context.new(outerContext: nil).init(); global actions = []; -print("Matching rawgrammar.leg : ", HardCodedPeg.grammar(stream, context, actions), "\n"); - -// Execute all actions after all matching +while(!stream.atEnd()) { + HardCodedPeg.grammar(stream, context, actions); -with(#peg); + with(#peg); + local definition = { for (actionAndContext in actions) { + actionAndContext.action.execute(actionAndContext.context); + } }; + if (definition == nil) continue; // end of file case + setInTopNamespace(definition.name, definition.expression); + without(#peg); -for (actionAndContext in actions) { - actionAndContext.action.execute(actionAndContext.context); + global actions = []; } - -without(#peg); println("\n--------- PEG ---------\n\n"); println(__namespaces__.peg); @@ -987,15 +1003,20 @@ global stream2 = newStream(readfile("rawminproto.leg")); global context2 = Context.new(outerContext: nil).init(); global actions2 = []; -print("\nMatching : ", peg.grammar(stream2, context2, actions2), "\n"); +while(!stream2.atEnd()) { + peg.grammar(stream2, context2, actions2); -with(#metaLanguageCircular); + with(#metaLanguageCircular); + local definition = { for (actionAndContext in actions2) { + actionAndContext.action.execute(actionAndContext.context); + } }; + if (definition == nil) continue; // end of file case + setInTopNamespace(definition.name, definition.expression); + without(#metaLanguageCircular); -for (actionAndContext in actions2) { - actionAndContext.action.execute(actionAndContext.context); + global actions2 = []; } -without(#metaLanguageCircular); println("\n--------- CIRCULAR META ---------\n\n"); println(__namespaces__.metaLanguageCircular); @@ -1003,15 +1024,20 @@ global stream2 = newStream(readfile("rawgrammar.leg")); global context2 = Context.new(outerContext: nil).init(); global actions2 = []; -print("\nMatching : ", peg.grammar(stream2, context2, actions2), "\n"); +while(!stream2.atEnd()) { + peg.grammar(stream2, context2, actions2); -with(#pegCircular); + with(#pegCircular); + local definition = { for (actionAndContext in actions2) { + actionAndContext.action.execute(actionAndContext.context); + } }; + if (definition == nil) continue; // end of file case + setInTopNamespace(definition.name, definition.expression); + without(#pegCircular); -for (actionAndContext in actions2) { - actionAndContext.action.execute(actionAndContext.context); + global actions2 = []; } -without(#pegCircular); println("\n--------- CIRCULAR PEG ---------\n\n"); println(__namespaces__.pegCircular); @@ -1044,11 +1070,13 @@ global actions3 = []; while(!stream3.atEnd()) { metaLanguage.start(stream3, context3, actions3); - for (actionAndContext in actions3) { + res = { for (actionAndContext in actions3) { actionAndContext.action.execute(actionAndContext.context); - } + } }; + //print(res, "\n"); //println(len(actions3)); //println(context3.variables.s); + //eval(context3.variables.s, nil); global actions3 = []; } diff --git a/rawgrammar.leg b/rawgrammar.leg index dd1a87e..d232fc9 100644 --- a/rawgrammar.leg +++ b/rawgrammar.leg @@ -1,6 +1,6 @@ -grammar = - - ( d:definition { setInTopNamespace(d.name, d.expression); } - ) + end-of-file +grammar = - ( d:definition { d; } + | end-of-file { nil; } + ) definition = i:identifier ASSIGN e:expression SEMI? { Definition.new(name: i, expression: e); }