Преглед на файлове

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

master
MaximeBarniaudy преди 11 месеца
родител
ревизия
c3125a863f
променени са 2 файла, в които са добавени 72 реда и са изтрити 44 реда
  1. +69
    -41
      grammar_parser.meta
  2. +3
    -3
      rawgrammar.leg

+ 69
- 41
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 = [];
}

+ 3
- 3
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); }

Зареждане…
Отказ
Запис