瀏覽代碼

Build Grammar objects whose methods are expression representations of grammar rules

master
MaximeBarniaudy 11 月之前
父節點
當前提交
b2e4198529
共有 1 個文件被更改,包括 359 次插入126 次删除
  1. +359
    -126
      grammar_parser.meta

+ 359
- 126
grammar_parser.meta 查看文件

@ -101,13 +101,17 @@ setInTopNamespace(__identifier, __value) {
__namespaces__.last()[__identifier] = __value; __namespaces__.last()[__identifier] = __value;
} }
println = (x) {
println(x) {
if (!x) { if (!x) {
print("\n");
if (len(__env__().__delegate__) == 0){
print("\n");
} else {
print(nil, "\n");
}
} else { } else {
print(x, "\n", full: 1); print(x, "\n", full: 1);
} }
};
}
Object.subtype(name) { self.new(__name__: name) } Object.subtype(name) { self.new(__name__: name) }
@ -137,7 +141,7 @@ Stream.peek() { !self.atEnd() && self.content[self.position] }
Context = Object.subtype(#Context); Context = Object.subtype(#Context);
Context.init() { self.variables = []; self; } Context.init() { self.variables = []; self; }
Context.declareVariable(var) { Context.declareVariable(var) {
found = 0;
local found = 0;
for (key in self.variables.keys()) { for (key in self.variables.keys()) {
if (key == var) { if (key == var) {
found = 1; found = 1;
@ -163,6 +167,18 @@ StringLiteral.match(stream, context, actions) {
} }
} }
StringLiteral.getMatchingExpression() {
//return `(@stream).match(@self.string) && ((@stream).position += len(@self.string)) && @true;
return `{
if (stream.match(@self.string)) {
stream.position += len(@self.string);
@true;
} else {
@false;
}
};
}
//StringLiteral.match(stream, context, actions) { //StringLiteral.match(stream, context, actions) {
// //
// n = len(self.string); // n = len(self.string);
@ -190,10 +206,10 @@ CharacterClass = Object.subtype(#CharacterClass);
CharacterClass.match(stream, context, actions) { CharacterClass.match(stream, context, actions) {
classLength = len(self.value);
i = 0;
prevChar = nil;
success = 0;
local classLength = len(self.value);
local i = 0;
local prevChar = nil;
local success = 0;
while (i < classLength && success == 0 && !stream.atEnd()) { while (i < classLength && success == 0 && !stream.atEnd()) {
@ -211,8 +227,8 @@ CharacterClass.match(stream, context, actions) {
// [a-z] case // [a-z] case
if (i+1 < classLength) { if (i+1 < classLength) {
// println("[a-z] case"); // println("[a-z] case");
rangeStart = prevChar;
rangeEnd = self.value[i+1];
local rangeStart = prevChar;
local rangeEnd = self.value[i+1];
// print("Range Start: ", rangeStart, " | "); // print("Range Start: ", rangeStart, " | ");
// print("Range End: ", rangeEnd, "\n"); // print("Range End: ", rangeEnd, "\n");
if (stream.peek() >= rangeStart if (stream.peek() >= rangeStart
@ -250,6 +266,73 @@ CharacterClass.match(stream, context, actions) {
success == 1; success == 1;
} }
CharacterClass.staticmatch(stream, context, actions, value) {
local classLength = len(value);
local i = 0;
local prevChar = nil;
local success = 0;
while (i < classLength && success == 0 && !stream.atEnd()) {
// [a] case
if (prevChar == nil) {
//println("[a] case");
prevChar = value[i];
if (stream.peek() == value[i]) {
success = 1;
}
} else if (prevChar != nil && value[i] == '-') {
// [a-z] case
if (i+1 < classLength) {
// println("[a-z] case");
local rangeStart = prevChar;
local rangeEnd = value[i+1];
// print("Range Start: ", rangeStart, " | ");
// print("Range End: ", rangeEnd, "\n");
if (stream.peek() >= rangeStart
&& stream.peek() <= rangeEnd
) {
success = 1;
}
prevChar = nil;
i = i + 1;
// [a-] case
} else {
// println("[a-] case");
if (stream.peek() == '-') {
success = 1;
}
}
// [ab] case
} else if (prevChar != nil && value[i] != '-') {
// println("[ab] case");
prevChar = value[i];
if (stream.peek() == value[i]) {
success = 1;
}
}
// print("prevChar: ", prevChar, "\n");
i = i + 1;
}
if (success == 1) {
stream.inc();
}
success == 1;
}
CharacterClass.getMatchingExpression() {
//return `CharacterClass.staticmatch(@stream, @context, @actions, @self.value);
return `{ CharacterClass.staticmatch(stream, context, actions, @self.value) };
}
// Dot // Dot
Dot = Object.subtype(#Dot); Dot = Object.subtype(#Dot);
@ -263,6 +346,11 @@ Dot.match(stream, context, actions) {
} }
} }
Dot.getMatchingExpression() {
//return `!(@stream).atEnd() && (@stream).inc() && @true;
return `{ !stream.atEnd() && stream.inc() && @true };
}
// Begin // Begin
Begin = Object.subtype(#Begin); Begin = Object.subtype(#Begin);
@ -272,6 +360,11 @@ Begin.match(stream, context, actions) {
true; true;
} }
Begin.getMatchingExpression() {
//return `(@stream).setLastBegin() && true;
return `{ stream.setLastBegin() && @true };
}
// End // End
End = Object.subtype(#End); End = Object.subtype(#End);
@ -281,6 +374,13 @@ End.match(stream, context, actions) {
true; true;
} }
End.getMatchingExpression() {
//return `((@context.variables).yytext = (@stream.content)[(@stream).lastBegin..(@stream).position].unescaped())
// && true;
return `{ (context.variables.yytext = stream.content[stream.lastBegin..stream.position].unescaped())
&& @true };
}
// Optional (? postfix operator) // Optional (? postfix operator)
Optional = Object.subtype(#Optional); Optional = Object.subtype(#Optional);
@ -290,6 +390,11 @@ Optional.match(stream, context, actions) {
true; true;
} }
Optional.getMatchingExpression() {
//return `(@self.expression.getMatchingExpression(stream, context, actions)) || @true;
return `{ (@self.expression.getMatchingExpression()); @true };
}
// Star // Star
Star = Object.subtype(#Star); Star = Object.subtype(#Star);
@ -299,6 +404,10 @@ Star.match(stream, context, actions) {
true; true;
} }
Star.getMatchingExpression() {
return `{ while (@self.expression.getMatchingExpression()) {} @true };
}
// Plus // Plus
Plus = Object.subtype(#Plus); Plus = Object.subtype(#Plus);
@ -312,12 +421,23 @@ Plus.match(stream, context, actions) {
} }
} }
Plus.getMatchingExpression() {
return `{
if (@self.expression.getMatchingExpression()) {
while (@self.expression.getMatchingExpression()) {}
@true;
} else {
@false;
}
};
}
// And // And
And = Object.subtype(#And); And = Object.subtype(#And);
And.match(stream, context, actions) { And.match(stream, context, actions) {
position = stream.position;
local position = stream.position;
if (self.expression.match(stream, context, actions) == true) { if (self.expression.match(stream, context, actions) == true) {
stream.position = position; stream.position = position;
@ -327,12 +447,24 @@ And.match(stream, context, actions) {
} }
} }
And.getMatchingExpression() {
return `{
local position = stream.position;
if (@self.expression.getMatchingExpression()) {
stream.position = position;
@true;
} else {
@false;
}
};
}
// Not // Not
Not = Object.subtype(#Not); Not = Object.subtype(#Not);
Not.match(stream, context, actions) { Not.match(stream, context, actions) {
position = stream.position;
local position = stream.position;
if (self.expression.match(stream, context, actions) == true) { if (self.expression.match(stream, context, actions) == true) {
stream.position = position; stream.position = position;
@ -342,6 +474,18 @@ Not.match(stream, context, actions) {
} }
} }
Not.getMatchingExpression() {
return `{
local position = stream.position;
if (@self.expression.getMatchingExpression()) {
stream.position = position;
@false;
} else {
@true;
}
};
}
// Sequence // Sequence
Sequence = Object.subtype(#Sequence); Sequence = Object.subtype(#Sequence);
@ -354,10 +498,10 @@ Sequence._match(stream, context, actions, index) {
} }
Sequence.match(stream, context, actions) { Sequence.match(stream, context, actions) {
initialActionCount = actions.length();
startingPosition = stream.position;
local initialActionCount = actions.length();
local startingPosition = stream.position;
success = self._match(stream, context, actions, 0);
local success = self._match(stream, context, actions, 0);
if (success == false) { if (success == false) {
while (actions.length() > initialActionCount) { while (actions.length() > initialActionCount) {
@ -369,6 +513,31 @@ Sequence.match(stream, context, actions) {
success; success;
} }
Sequence._getMatchingExpression(index) {
if (index == self.length() - 1) {
return self[index].getMatchingExpression();
}
return `(@self[index].getMatchingExpression())
&& @self._getMatchingExpression(index + 1);
}
Sequence.getMatchingExpression() {
return `{
local initialActionCount = actions.length();
local startingPosition = stream.position;
({
(@self._getMatchingExpression(0));
} || {
while (actions.length() > initialActionCount) {
actions.pop();
}
stream.position = startingPosition;
@false;
});
}
}
// Alternation // Alternation
Alternation = Object.subtype(#Alternation); Alternation = Object.subtype(#Alternation);
@ -384,6 +553,18 @@ Alternation.match(stream, context, actions) {
return self._match(stream, context, actions, 0); return self._match(stream, context, actions, 0);
} }
Alternation._getMatchingExpression(index) {
if (index == self.length() - 1) {
return self[index].getMatchingExpression();
}
return `(@self[index].getMatchingExpression())
|| @self._getMatchingExpression(index + 1);
}
Alternation.getMatchingExpression() {
return `{ @self._getMatchingExpression(0) };
}
// Action // Action
Action = Object.subtype(#Action); Action = Object.subtype(#Action);
@ -393,6 +574,10 @@ Action.match(stream, context, actions) {
true; true;
} }
Action.getMatchingExpression() {
return `{ actions.push([action: @self, context: context]); @true; }
}
Action.execute(context) { Action.execute(context) {
// Declare all variables that a value is set to in the context // Declare all variables that a value is set to in the context
@ -403,7 +588,7 @@ Action.execute(context) {
} }
// Evaluate the parse tree and return to outer context if needed // Evaluate the parse tree and return to outer context if needed
returnValue = eval(self.parseTree, env: context.variables);
local returnValue = eval(self.parseTree, env: context.variables);
if (context.outerContext != nil) { if (context.outerContext != nil) {
context.outerContext.variables[context.returnValueName] = returnValue; context.outerContext.variables[context.returnValueName] = returnValue;
} }
@ -423,16 +608,28 @@ ParseTimeAction.match(stream, context, actions) {
} }
} }
ParseTimeAction.getMatchingExpression() {
return `{ (@self.action).execute(context) };
}
// Assignment // Assignment
Assignment = Object.subtype(#Assignment); Assignment = Object.subtype(#Assignment);
Assignment.match(stream, context, actions) { Assignment.match(stream, context, actions) {
context.declareVariable(self.name); context.declareVariable(self.name);
innerContext = Context.new(outerContext: context, returnValueName: self.name).init();
local innerContext = Context.new(outerContext: context, returnValueName: self.name).init();
self.rule.match(stream, innerContext, actions); self.rule.match(stream, innerContext, actions);
} }
Assignment.getMatchingExpression() {
return `{
context.declareVariable(@self.name);
local context = Context.new(outerContext: context, returnValueName: @self.name).init();
@self.rule.getMatchingExpression();
}
}
// RuleCall // RuleCall
RuleCall = Object.subtype(#RuleCall); RuleCall = Object.subtype(#RuleCall);
@ -440,29 +637,72 @@ RuleCall = Object.subtype(#RuleCall);
RuleCall.match(stream, context, actions) { RuleCall.match(stream, context, actions) {
//if (rules[self.name] == nil) { print("Trying to call undefined rule: ", self.name, "\n"); exit(); } //if (rules[self.name] == nil) { print("Trying to call undefined rule: ", self.name, "\n"); exit(); }
//print("calling rule ", self.name, " | ", stream.position, "\n"); //print("calling rule ", self.name, " | ", stream.position, "\n");
res = get(self.name).match(stream, context, actions);
local res = get(self.name).match(stream, context, actions);
//print("matching rule ", self.name, ": ", res, "\n"); //print("matching rule ", self.name, ": ", res, "\n");
res; res;
} }
RuleCall.getMatchingExpression() {
//print("Calling rule ", self.name, "\n");
//local res = `{get(@self.name).getMatchingExpression(@stream, @context, @actions).__eval__()};
//if (innerContext == nil) {
`{ Invoke.new(self: self, method: @self.name, arguments: [stream, context, actions]).__eval__() };
//} else {
// `{ self.rules[@self.name](stream, @innerContext, actions) };
//}
//print("Pos ", stream.position, " | Called rule ", self.name, "\n");
}
// NamespacedRuleCall // NamespacedRuleCall
NamespacedRuleCall = Object.subtype(#NamespacedRuleCall); NamespacedRuleCall = Object.subtype(#NamespacedRuleCall);
NamespacedRuleCall.match(stream, context, actions) {
NamespacedRuleCall.match() {
with(self.namespace); with(self.namespace);
res = get(self.name).match(stream, context, actions);
local res = get(self.name).match(stream, context, actions);
without(); without();
res; res;
} }
NamespacedRuleCall.getMatchingExpression(innerContext) {
//return `{
// with(@self.namespace);
// local res = get(@self.name).getMatchingExpression(@stream, @context, @actions).__eval__();
// without();
// res;
//}
//if (innerContext == nil) {
`{ Invoke.new(self: @get(self.namespace), method: @self.name, arguments: [stream, context, actions]).__eval__() };
//} else {
// `{ (@get(self.namespace)).rules[@self.name](stream, @innerContext, actions) };
//}
}
Definition = Object.subtype(#Definition); Definition = Object.subtype(#Definition);
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
)
)
}
}
// ----- Grammar of Meta Language (Minimal) ----- // ----- Grammar of Meta Language (Minimal) -----
hcmeta = with(#HardCodedMeta);
with(#HardCodedMeta);
hcmeta.metaStatement =
metaStatement =
Alternation.new() Alternation.new()
.push(Sequence.new() .push(Sequence.new()
.push(Assignment.new(name: #b, rule: RuleCall.new(name: #block))) .push(Assignment.new(name: #b, rule: RuleCall.new(name: #block)))
@ -477,7 +717,7 @@ hcmeta.metaStatement =
.push(Action.new(parseTree: `{ e; })) .push(Action.new(parseTree: `{ e; }))
); );
hcmeta.metaExpression =
metaExpression =
Alternation.new(id: 1234) Alternation.new(id: 1234)
.push(Sequence.new() .push(Sequence.new()
.push(Assignment.new(name: #p, rule: RuleCall.new(name: #metaPrimary))) .push(Assignment.new(name: #p, rule: RuleCall.new(name: #metaPrimary)))
@ -509,7 +749,7 @@ hcmeta.metaExpression =
.push(Action.new(parseTree: `{ pf; })) .push(Action.new(parseTree: `{ pf; }))
); );
hcmeta.metaPostfix =
metaPostfix =
Sequence.new() Sequence.new()
.push(Assignment.new(name: #p, rule: RuleCall.new(name: #metaPrimary))) .push(Assignment.new(name: #p, rule: RuleCall.new(name: #metaPrimary)))
.push(Star.new(expression: Alternation.new() .push(Star.new(expression: Alternation.new()
@ -537,7 +777,7 @@ hcmeta.metaPostfix =
)) ))
.push(Action.new(parseTree: `{ p; })); .push(Action.new(parseTree: `{ p; }));
hcmeta.args =
args =
Sequence.new() Sequence.new()
.push(RuleCall.new(name: #lparen)) .push(RuleCall.new(name: #lparen))
.push(Assignment.new(name: #a, rule: RuleCall.new(name: #mklist))) .push(Assignment.new(name: #a, rule: RuleCall.new(name: #mklist)))
@ -573,23 +813,23 @@ hcmeta.args =
.push(RuleCall.new(name: #rparen)) .push(RuleCall.new(name: #rparen))
.push(Action.new(parseTree: `{ a; })); .push(Action.new(parseTree: `{ a; }));
hcmeta.mklist = Action.new(parseTree: `{ Object.new(); });
mklist = Action.new(parseTree: `{ Object.new(); });
hcmeta.metaPrimary =
metaPrimary =
Alternation.new() Alternation.new()
.push(RuleCall.new(name: #nil)) .push(RuleCall.new(name: #nil))
.push(RuleCall.new(name: #number)) .push(RuleCall.new(name: #number))
.push(RuleCall.new(name: #metaVar)) .push(RuleCall.new(name: #metaVar))
.push(RuleCall.new(name: #metaSubExpr)); .push(RuleCall.new(name: #metaSubExpr));
hcmeta.metaSubExpr =
metaSubExpr =
Sequence.new() Sequence.new()
.push(RuleCall.new(name: #lparen)) .push(RuleCall.new(name: #lparen))
.push(Assignment.new(name: #e, rule: RuleCall.new(name: #metaExpression))) .push(Assignment.new(name: #e, rule: RuleCall.new(name: #metaExpression)))
.push(RuleCall.new(name: #rparen)) .push(RuleCall.new(name: #rparen))
.push(Action.new(parseTree = `{ e; }));
.push(Action.new(parseTree: `{ e; }));
hcmeta.block =
block =
Sequence.new() Sequence.new()
.push(RuleCall.new(name: #lbrace)) .push(RuleCall.new(name: #lbrace))
.push(Assignment.new(name: #b, rule: RuleCall.new(name: #mklist))) .push(Assignment.new(name: #b, rule: RuleCall.new(name: #mklist)))
@ -603,7 +843,7 @@ hcmeta.block =
.push(RuleCall.new(name: #rbrace)) .push(RuleCall.new(name: #rbrace))
.push(Action.new(parseTree: `{ Block.new(body: b); })); .push(Action.new(parseTree: `{ Block.new(body: b); }));
hcmeta.number =
number =
Alternation.new() Alternation.new()
.push(Sequence.new() .push(Sequence.new()
.push(StringLiteral.new(string: "-")) .push(StringLiteral.new(string: "-"))
@ -620,7 +860,7 @@ hcmeta.number =
.push(Action.new(parseTree: `{ n })) .push(Action.new(parseTree: `{ n }))
); );
hcmeta.unsign =
unsign =
Sequence.new() Sequence.new()
.push(Begin.new()) .push(Begin.new())
.push(Plus.new(expression: RuleCall.new(name: #digit))) .push(Plus.new(expression: RuleCall.new(name: #digit)))
@ -628,12 +868,12 @@ hcmeta.unsign =
.push(RuleCall.new(name: #ws)) .push(RuleCall.new(name: #ws))
.push(Action.new(parseTree: `{ yytext.asInteger(10); })); .push(Action.new(parseTree: `{ yytext.asInteger(10); }));
hcmeta.metaVar =
metaVar =
Sequence.new() Sequence.new()
.push(Assignment.new(name: #i, rule: RuleCall.new(name: #metaId))) .push(Assignment.new(name: #i, rule: RuleCall.new(name: #metaId)))
.push(Action.new(parseTree: `{ GetVar.new(name: i); })); .push(Action.new(parseTree: `{ GetVar.new(name: i); }));
hcmeta.metaId =
metaId =
Sequence.new() Sequence.new()
.push(Begin.new()) .push(Begin.new())
.push(RuleCall.new(name: #letter)) .push(RuleCall.new(name: #letter))
@ -642,52 +882,52 @@ hcmeta.metaId =
.push(RuleCall.new(name: #ws)) .push(RuleCall.new(name: #ws))
.push(Action.new(parseTree: `{ intern(yytext); })); .push(Action.new(parseTree: `{ intern(yytext); }));
hcmeta.digit = CharacterClass.new(value: "0-9");
hcmeta.letter = CharacterClass.new(value: "A-Za-z_");
hcmeta.alnum =
digit = CharacterClass.new(value: "0-9");
letter = CharacterClass.new(value: "A-Za-z_");
alnum =
Alternation.new() Alternation.new()
.push(RuleCall.new(name: #letter)) .push(RuleCall.new(name: #letter))
.push(RuleCall.new(name: #digit)); .push(RuleCall.new(name: #digit));
hcmeta.nil =
nil =
Sequence.new() Sequence.new()
.push(StringLiteral.new(string: "nil")) .push(StringLiteral.new(string: "nil"))
.push(Not.new(expression: RuleCall.new(name: #alnum))) .push(Not.new(expression: RuleCall.new(name: #alnum)))
.push(RuleCall.new(name: #ws)); .push(RuleCall.new(name: #ws));
hcmeta.semi = Sequence.new().push(StringLiteral.new(string: ";" )).push(RuleCall.new(name: #ws));
hcmeta.comma = Sequence.new().push(StringLiteral.new(string: "," )).push(RuleCall.new(name: #ws));
hcmeta.lparen = Sequence.new().push(StringLiteral.new(string: "(" )).push(RuleCall.new(name: #ws));
hcmeta.rparen = Sequence.new().push(StringLiteral.new(string: ")" )).push(RuleCall.new(name: #ws));
hcmeta.lbrak = Sequence.new().push(StringLiteral.new(string: "[" )).push(RuleCall.new(name: #ws));
hcmeta.rbrak = Sequence.new().push(StringLiteral.new(string: "]" )).push(RuleCall.new(name: #ws));
hcmeta.lbrace = Sequence.new().push(StringLiteral.new(string: "{" )).push(RuleCall.new(name: #ws));
hcmeta.rbrace = Sequence.new().push(StringLiteral.new(string: "}" )).push(RuleCall.new(name: #ws));
semi = Sequence.new().push(StringLiteral.new(string: ";" )).push(RuleCall.new(name: #ws));
comma = Sequence.new().push(StringLiteral.new(string: "," )).push(RuleCall.new(name: #ws));
lparen = Sequence.new().push(StringLiteral.new(string: "(" )).push(RuleCall.new(name: #ws));
rparen = Sequence.new().push(StringLiteral.new(string: ")" )).push(RuleCall.new(name: #ws));
lbrak = Sequence.new().push(StringLiteral.new(string: "[" )).push(RuleCall.new(name: #ws));
rbrak = Sequence.new().push(StringLiteral.new(string: "]" )).push(RuleCall.new(name: #ws));
lbrace = Sequence.new().push(StringLiteral.new(string: "{" )).push(RuleCall.new(name: #ws));
rbrace = Sequence.new().push(StringLiteral.new(string: "}" )).push(RuleCall.new(name: #ws));
hcmeta.assign =
assign =
Sequence.new() Sequence.new()
.push(StringLiteral.new(string: "=")) .push(StringLiteral.new(string: "="))
.push(Not.new(expression: CharacterClass.new(value: "="))) .push(Not.new(expression: CharacterClass.new(value: "=")))
.push(RuleCall.new(name: #ws)); .push(RuleCall.new(name: #ws));
hcmeta.dot =
dot =
Sequence.new() Sequence.new()
.push(StringLiteral.new(string: ".")) .push(StringLiteral.new(string: "."))
.push(Not.new(expression: CharacterClass.new(value: "."))) .push(Not.new(expression: CharacterClass.new(value: ".")))
.push(RuleCall.new(name: #ws)); .push(RuleCall.new(name: #ws));
hcmeta.colon =
colon =
Sequence.new() Sequence.new()
.push(StringLiteral.new(string: ":")) .push(StringLiteral.new(string: ":"))
.push(Not.new(expression: CharacterClass.new(value: ":"))) .push(Not.new(expression: CharacterClass.new(value: ":")))
.push(RuleCall.new(name: #ws)); .push(RuleCall.new(name: #ws));
hcmeta.end_of_file = Not.new(expression: Dot.new());
end_of_file = Not.new(expression: Dot.new());
hcmeta.end_of_line =
end_of_line =
Alternation.new() Alternation.new()
.push(StringLiteral.new(string: "\r\n")) .push(StringLiteral.new(string: "\r\n"))
.push(StringLiteral.new(string: "\n")) .push(StringLiteral.new(string: "\n"))
.push(StringLiteral.new(string: "\r")); .push(StringLiteral.new(string: "\r"));
hcmeta.comment =
comment =
Sequence.new() Sequence.new()
.push(StringLiteral.new(string: "//")) .push(StringLiteral.new(string: "//"))
.push(Star.new(expression: .push(Star.new(expression:
@ -697,13 +937,13 @@ hcmeta.comment =
)) ))
.push(RuleCall.new(name: #end_of_line)); .push(RuleCall.new(name: #end_of_line));
hcmeta.space =
space =
Alternation.new() Alternation.new()
.push(StringLiteral.new(string: " ")) .push(StringLiteral.new(string: " "))
.push(StringLiteral.new(string: "\t")) .push(StringLiteral.new(string: "\t"))
.push(RuleCall.new(name: #end_of_line)); .push(RuleCall.new(name: #end_of_line));
hcmeta.ws =
ws =
Star.new(expression: Alternation.new() Star.new(expression: Alternation.new()
.push(RuleCall.new(name: #space)) .push(RuleCall.new(name: #space))
.push(RuleCall.new(name: #comment)) .push(RuleCall.new(name: #comment))
@ -711,9 +951,9 @@ hcmeta.ws =
// ----- Grammar of Grammars ----- // ----- Grammar of Grammars -----
hcpeg = with(#HardCodedPeg);
with(#HardCodedPeg);
hcpeg.grammar =
grammar =
Sequence.new() Sequence.new()
.push(RuleCall.new(name: #ws)) .push(RuleCall.new(name: #ws))
.push(Plus.new(expression: Sequence.new() .push(Plus.new(expression: Sequence.new()
@ -722,7 +962,7 @@ hcpeg.grammar =
)) ))
.push(RuleCall.new(name: #end_of_file)); .push(RuleCall.new(name: #end_of_file));
hcpeg.definition =
definition =
Sequence.new() Sequence.new()
.push(Assignment.new(name: #i, rule: RuleCall.new(name: #identifier))) .push(Assignment.new(name: #i, rule: RuleCall.new(name: #identifier)))
.push(RuleCall.new(name: #assign)) .push(RuleCall.new(name: #assign))
@ -730,7 +970,7 @@ hcpeg.definition =
.push(Optional.new(expression: RuleCall.new(name: #semi))) .push(Optional.new(expression: RuleCall.new(name: #semi)))
.push(Action.new(parseTree: `{ Definition.new(name: i, expression: e); })); .push(Action.new(parseTree: `{ Definition.new(name: i, expression: e); }));
hcpeg.expression =
expression =
Alternation.new() Alternation.new()
.push(Sequence.new() .push(Sequence.new()
.push(Assignment.new(name: #s, rule: RuleCall.new(name: #sequence))) .push(Assignment.new(name: #s, rule: RuleCall.new(name: #sequence)))
@ -748,7 +988,7 @@ hcpeg.expression =
.push(Action.new(parseTree: `{ s1; })) .push(Action.new(parseTree: `{ s1; }))
); );
hcpeg.sequence =
sequence =
Sequence.new() Sequence.new()
.push(Assignment.new(name: #p, rule: RuleCall.new(name: #prefix))) .push(Assignment.new(name: #p, rule: RuleCall.new(name: #prefix)))
.push(Action.new(parseTree: `{ p = Sequence.new().push(p); })) .push(Action.new(parseTree: `{ p = Sequence.new().push(p); }))
@ -758,7 +998,7 @@ hcpeg.sequence =
)) ))
.push(Action.new(parseTree: `{ p; })); .push(Action.new(parseTree: `{ p; }));
hcpeg.prefix =
prefix =
Alternation.new() Alternation.new()
.push(Sequence.new() .push(Sequence.new()
.push(RuleCall.new(name: #and)) .push(RuleCall.new(name: #and))
@ -781,7 +1021,7 @@ hcpeg.prefix =
) )
); );
hcpeg.suffix =
suffix =
Sequence.new() Sequence.new()
.push(Assignment.new(name: #p, rule: RuleCall.new(name: #primary))) .push(Assignment.new(name: #p, rule: RuleCall.new(name: #primary)))
.push(Optional.new(expression: Alternation.new() .push(Optional.new(expression: Alternation.new()
@ -800,7 +1040,7 @@ hcpeg.suffix =
)) ))
.push(Action.new(parseTree: `{ p; })); .push(Action.new(parseTree: `{ p; }));
hcpeg.primary =
primary =
Alternation.new() Alternation.new()
.push(Sequence.new() .push(Sequence.new()
.push(Assignment.new(name: #i1, rule: RuleCall.new(name: #identifier))) .push(Assignment.new(name: #i1, rule: RuleCall.new(name: #identifier)))
@ -845,7 +1085,7 @@ hcpeg.primary =
.push(Action.new(parseTree: `{ End.new(); })) .push(Action.new(parseTree: `{ End.new(); }))
); );
hcpeg.identifier =
identifier =
Sequence.new() Sequence.new()
.push(Begin.new()) .push(Begin.new())
.push(CharacterClass.new(value: "-a-zA-Z_")) .push(CharacterClass.new(value: "-a-zA-Z_"))
@ -854,7 +1094,7 @@ hcpeg.identifier =
.push(RuleCall.new(name: #ws)) .push(RuleCall.new(name: #ws))
.push(Action.new(parseTree: `{ intern(yytext); })); .push(Action.new(parseTree: `{ intern(yytext); }));
hcpeg.ruleCall =
ruleCall =
Alternation.new() Alternation.new()
.push(Sequence.new() .push(Sequence.new()
.push(Assignment.new(name: #n, rule: RuleCall.new(name: #identifier))) .push(Assignment.new(name: #n, rule: RuleCall.new(name: #identifier)))
@ -867,7 +1107,7 @@ hcpeg.ruleCall =
.push(Action.new(parseTree: `{ RuleCall.new(name: i); })) .push(Action.new(parseTree: `{ RuleCall.new(name: i); }))
); );
hcpeg.literal =
literal =
Alternation.new() Alternation.new()
.push(Sequence.new() .push(Sequence.new()
.push(CharacterClass.new(value: "\'")) .push(CharacterClass.new(value: "\'"))
@ -894,7 +1134,7 @@ hcpeg.literal =
.push(Action.new(parseTree: `{ StringLiteral.new(string: yytext); })) .push(Action.new(parseTree: `{ StringLiteral.new(string: yytext); }))
); );
hcpeg.class =
class =
Sequence.new() Sequence.new()
.push(StringLiteral.new(string: "[")) .push(StringLiteral.new(string: "["))
.push(Begin.new()) .push(Begin.new())
@ -907,7 +1147,7 @@ hcpeg.class =
.push(RuleCall.new(name: #ws)) .push(RuleCall.new(name: #ws))
.push(Action.new(parseTree: `{ CharacterClass.new(value: yytext); })); .push(Action.new(parseTree: `{ CharacterClass.new(value: yytext); }));
hcpeg.range =
range =
Alternation.new() Alternation.new()
.push(Sequence.new() .push(Sequence.new()
.push(RuleCall.new(name: #char)) .push(RuleCall.new(name: #char))
@ -918,7 +1158,7 @@ hcpeg.range =
RuleCall.new(name: #char) RuleCall.new(name: #char)
); );
hcpeg.char =
char =
Alternation.new() Alternation.new()
.push(Sequence.new() .push(Sequence.new()
.push(StringLiteral.new(string: "\\")) .push(StringLiteral.new(string: "\\"))
@ -940,47 +1180,47 @@ hcpeg.char =
.push(Dot.new()) .push(Dot.new())
); );
hcpeg.action =
action =
Sequence.new() Sequence.new()
.push(Assignment.new(name: #m, rule: NamespacedRuleCall.new(namespace: #HardCodedMeta, name: #block))) .push(Assignment.new(name: #m, rule: NamespacedRuleCall.new(namespace: #HardCodedMeta, name: #block)))
.push(RuleCall.new(name: #ws)) .push(RuleCall.new(name: #ws))
.push(Action.new(parseTree: `{ Action.new(parseTree: m); })); .push(Action.new(parseTree: `{ Action.new(parseTree: m); }));
hcpeg.bar = Sequence.new().push(StringLiteral.new(string: "|")).push(RuleCall.new(name: #ws));
hcpeg.not = Sequence.new().push(StringLiteral.new(string: "!")).push(RuleCall.new(name: #ws));
hcpeg.query = Sequence.new().push(StringLiteral.new(string: "?")).push(RuleCall.new(name: #ws));
hcpeg.begin = Sequence.new().push(StringLiteral.new(string: "<")).push(RuleCall.new(name: #ws));
hcpeg.end = Sequence.new().push(StringLiteral.new(string: ">")).push(RuleCall.new(name: #ws));
hcpeg.tilde = Sequence.new().push(StringLiteral.new(string: "~")).push(RuleCall.new(name: #ws));
hcpeg.rpercent = Sequence.new().push(StringLiteral.new(string: "%}")).push(RuleCall.new(name: #ws));
bar = Sequence.new().push(StringLiteral.new(string: "|")).push(RuleCall.new(name: #ws));
not = Sequence.new().push(StringLiteral.new(string: "!")).push(RuleCall.new(name: #ws));
query = Sequence.new().push(StringLiteral.new(string: "?")).push(RuleCall.new(name: #ws));
begin = Sequence.new().push(StringLiteral.new(string: "<")).push(RuleCall.new(name: #ws));
end = Sequence.new().push(StringLiteral.new(string: ">")).push(RuleCall.new(name: #ws));
tilde = Sequence.new().push(StringLiteral.new(string: "~")).push(RuleCall.new(name: #ws));
rpercent = Sequence.new().push(StringLiteral.new(string: "%}")).push(RuleCall.new(name: #ws));
hcpeg.ccolon = Sequence.new().push(StringLiteral.new(string: "::")).push(RuleCall.new(name: #ws));
ccolon = Sequence.new().push(StringLiteral.new(string: "::")).push(RuleCall.new(name: #ws));
hcpeg.and =
and =
Sequence.new() Sequence.new()
.push(StringLiteral.new(string: "&")) .push(StringLiteral.new(string: "&"))
.push(Not.new(expression: CharacterClass.new(value: "&="))) .push(Not.new(expression: CharacterClass.new(value: "&=")))
.push(RuleCall.new(name: #ws)); .push(RuleCall.new(name: #ws));
hcpeg.plus =
plus =
Sequence.new() Sequence.new()
.push(StringLiteral.new(string: "+")) .push(StringLiteral.new(string: "+"))
.push(Not.new(expression: CharacterClass.new(value: "+="))) .push(Not.new(expression: CharacterClass.new(value: "+=")))
.push(RuleCall.new(name: #ws)); .push(RuleCall.new(name: #ws));
hcpeg.star =
star =
Sequence.new() Sequence.new()
.push(StringLiteral.new(string: "*")) .push(StringLiteral.new(string: "*"))
.push(Not.new(expression: CharacterClass.new(value: "="))) .push(Not.new(expression: CharacterClass.new(value: "=")))
.push(RuleCall.new(name: #ws)); .push(RuleCall.new(name: #ws));
hcpeg.end_of_file = Not.new(expression: Dot.new());
end_of_file = Not.new(expression: Dot.new());
hcpeg.end_of_line =
end_of_line =
Alternation.new() Alternation.new()
.push(StringLiteral.new(string: "\r\n")) .push(StringLiteral.new(string: "\r\n"))
.push(StringLiteral.new(string: "\n")) .push(StringLiteral.new(string: "\n"))
.push(StringLiteral.new(string: "\r")); .push(StringLiteral.new(string: "\r"));
hcpeg.comment =
comment =
Sequence.new() Sequence.new()
.push(StringLiteral.new(string: "#")) .push(StringLiteral.new(string: "#"))
.push(Star.new(expression: .push(Star.new(expression:
@ -990,13 +1230,13 @@ hcpeg.comment =
)) ))
.push(RuleCall.new(name: #end_of_line)); .push(RuleCall.new(name: #end_of_line));
hcpeg.space =
space =
Alternation.new() Alternation.new()
.push(StringLiteral.new(string: " ")) .push(StringLiteral.new(string: " "))
.push(StringLiteral.new(string: "\t")) .push(StringLiteral.new(string: "\t"))
.push(RuleCall.new(name: #end_of_line)); .push(RuleCall.new(name: #end_of_line));
hcpeg.ws =
ws =
Star.new(expression: Alternation.new() Star.new(expression: Alternation.new()
.push(RuleCall.new(name: #space)) .push(RuleCall.new(name: #space))
.push(RuleCall.new(name: #comment)) .push(RuleCall.new(name: #comment))
@ -1004,11 +1244,21 @@ hcpeg.ws =
// ----- Main ----- // ----- Main -----
stream = newStream(readfile("rawminproto.leg"));
context = Context.new(outerContext: nil).init();
actions = [];
without(all: 1);
HardCodedPeg = Grammar.new();
HardCodedMeta = Grammar.new();
HardCodedPeg.addRulesFromNamespace(#HardCodedPeg);
HardCodedMeta.addRulesFromNamespace(#HardCodedMeta);
print("Matching rawminproto.leg : ", grammar.match(stream, context, actions), "\n");
HardCodedPeg.__delegate__ = HardCodedMeta;
global stream = newStream(readfile("rawminproto.leg"));
global context = Context.new(outerContext: nil).init();
global actions = [];
print("Matching rawminproto.leg : ", HardCodedPeg.grammar(stream, context, actions), "\n");
with(#metaLanguage); with(#metaLanguage);
for (actionAndContext in actions) { for (actionAndContext in actions) {
@ -1018,29 +1268,11 @@ without(#metaLanguage);
println("\n--------- META ---------\n\n"); println("\n--------- META ---------\n\n");
println(__namespaces__.metaLanguage); println(__namespaces__.metaLanguage);
//stream = newStream(readfile("rawMetaGrammar.leg"));
//context = Context.new(outerContext: nil).init();
//actions = [];
//
//print("Matching : ", grammar.match(stream, context, actions), "\n");
//
//// Execute all actions after all matching
//// Open the namespace where rules will be declared
//with(#metaLanguage);
//
//for (actionAndContext in actions) {
// actionAndContext.action.execute(actionAndContext.context);
//}
//
//println("\n--------- META ---------\n\n");
//println(__namespaces__.metaLanguage);
//without(#metaLanguage);
stream = newStream(readfile("rawgrammar.leg"));
context = Context.new(outerContext: nil).init();
actions = [];
global stream = newStream(readfile("rawgrammar.leg"));
global context = Context.new(outerContext: nil).init();
global actions = [];
print("Matching : ", grammar.match(stream, context, actions), "\n");
print("Matching rawgrammar.leg : ", HardCodedPeg.grammar(stream, context, actions), "\n");
// Execute all actions after all matching // Execute all actions after all matching
@ -1055,17 +1287,20 @@ println("\n--------- PEG ---------\n\n");
println(__namespaces__.peg); println(__namespaces__.peg);
// Circularity test // Circularity test
without(all: 1);
with(#metaLanguage);
with(#peg);
peg = Grammar.new();
metaLanguage = Grammar.new();
peg.addRulesFromNamespace(#peg);
metaLanguage.addRulesFromNamespace(#metaLanguage);
stream2 = newStream(readfile("rawminproto.leg"));
//stream2 = newStream("a = b:c::d { print(a[b].c); }");
context2 = Context.new(outerContext: nil).init();
actions2 = [];
peg.__delegate__ = metaLanguage;
print("\nMatching : ", grammar.match(stream2, context2, actions2), "\n");
global stream2 = newStream(readfile("rawminproto.leg"));
global context2 = Context.new(outerContext: nil).init();
global actions2 = [];
print("\nMatching : ", peg.grammar(stream2, context2, actions2), "\n");
with(#metaLanguageCircular); with(#metaLanguageCircular);
@ -1077,11 +1312,11 @@ without(#metaLanguageCircular);
println("\n--------- CIRCULAR META ---------\n\n"); println("\n--------- CIRCULAR META ---------\n\n");
println(__namespaces__.metaLanguageCircular); println(__namespaces__.metaLanguageCircular);
stream2 = newStream(readfile("rawgrammar.leg"));
context2 = Context.new(outerContext: nil).init();
actions2 = [];
global stream2 = newStream(readfile("rawgrammar.leg"));
global context2 = Context.new(outerContext: nil).init();
global actions2 = [];
print("\nMatching : ", grammar.match(stream2, context2, actions2), "\n");
print("\nMatching : ", peg.grammar(stream2, context2, actions2), "\n");
with(#pegCircular); with(#pegCircular);
@ -1093,10 +1328,8 @@ without(#pegCircular);
println("\n--------- CIRCULAR PEG ---------\n\n"); println("\n--------- CIRCULAR PEG ---------\n\n");
println(__namespaces__.pegCircular); println(__namespaces__.pegCircular);
without(all: 1);
compareGrammars(grammar1, grammar2) { compareGrammars(grammar1, grammar2) {
success = 1;
local success = 1;
for (key in __namespaces__[grammar1].keys()) { for (key in __namespaces__[grammar1].keys()) {
if (key == #__nsname__) continue; if (key == #__nsname__) continue;

Loading…
取消
儲存