Explorar el Código

Move side effect of variable assignment in namespace out of grammar for logic and ease of use reasons

master
MaximeBarniaudy hace 11 meses
padre
commit
c3125a863f
Se han modificado 2 ficheros con 72 adiciones y 44 borrados
  1. +69
    -41
      grammar_parser.meta
  2. +3
    -3
      rawgrammar.leg

+ 69
- 41
grammar_parser.meta Ver fichero

@ -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 = [];
}

+ 3
- 3
rawgrammar.leg Ver fichero

@ -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); }

Cargando…
Cancelar
Guardar