Просмотр исходного кода

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

master
MaximeBarniaudy 11 месяцев назад
Родитель
Сommit
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); }

Загрузка…
Отмена
Сохранить