|
|
@ -20,7 +20,6 @@ newStream(string) { |
|
|
|
position: 0, |
|
|
|
limit: len(string) |
|
|
|
); |
|
|
|
print("Created new stream object: { position: ", self.position, ", limit: ", self.limit, ", !atEnd(): ", !self.atEnd(), " }\n"); |
|
|
|
self; |
|
|
|
} |
|
|
|
|
|
|
@ -174,7 +173,7 @@ Begin.match(stream, context, rules, actions) { |
|
|
|
End = Object.subtype(#End); |
|
|
|
|
|
|
|
End.match(stream, context, rules, actions) { |
|
|
|
context.variables.yytext = stream.content[stream.lastBegin..stream.position]; |
|
|
|
context.variables.yytext = stream.content[stream.lastBegin..stream.position].unescaped(); |
|
|
|
1; |
|
|
|
} |
|
|
|
|
|
|
@ -311,6 +310,19 @@ Action.execute(context) { |
|
|
|
context.outerContext.variables[context.returnValueName] = returnValue; |
|
|
|
} |
|
|
|
|
|
|
|
returnValue; |
|
|
|
} |
|
|
|
|
|
|
|
// Parse-time Action |
|
|
|
|
|
|
|
ParseTimeAction = Object.subtype(#ParseTimeAction); |
|
|
|
|
|
|
|
ParseTimeAction.match(stream, context, rules, actions) { |
|
|
|
if(self.action.execute(context)) { |
|
|
|
1; |
|
|
|
} else { |
|
|
|
0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Assignment |
|
|
@ -328,6 +340,7 @@ Assignment.match(stream, context, rules, actions) { |
|
|
|
RuleCall = Object.subtype(#RuleCall); |
|
|
|
|
|
|
|
RuleCall.match(stream, context, rules, actions) { |
|
|
|
if (rules[self.name] == nil) { print("Trying to call undefined rule: ", self.name, "\n"); exit(); } |
|
|
|
rules[self.name].match(stream, context, rules, actions); |
|
|
|
} |
|
|
|
|
|
|
@ -348,7 +361,7 @@ rules.grammar = Sequence.new() |
|
|
|
.push(Action.new(parseTree: `{ g[d.name] = d.expression; })) |
|
|
|
)) |
|
|
|
.push(RuleCall.new(name: #end_of_file)) |
|
|
|
.push(Action.new(parseTree: `{ print(g, full: Object.new()); })); |
|
|
|
.push(Action.new(parseTree: `{ g; })); |
|
|
|
|
|
|
|
|
|
|
|
Definition = Object.subtype(#Definition); |
|
|
@ -503,7 +516,7 @@ rules.identifier = Sequence.new() |
|
|
|
.push(Star.new(expression: CharacterClass.new(value: "-a-zA-Z_0-9"))) |
|
|
|
.push(End.new()) |
|
|
|
.push(RuleCall.new(name: #ws)) |
|
|
|
.push(Action.new(parseTree: `{ yytext })); |
|
|
|
.push(Action.new(parseTree: `{ intern(yytext); })); |
|
|
|
|
|
|
|
// ruleCallIdent = < [-a-zA-Z_][-a-zA-Z_0-9]* > - { newIdentifier(yytext); } |
|
|
|
|
|
|
@ -529,7 +542,7 @@ rules.literal = Alternation.new() |
|
|
|
.push(End.new()) |
|
|
|
.push(CharacterClass.new(value: "\'")) |
|
|
|
.push(RuleCall.new(name: #ws)) |
|
|
|
.push(Action.new(parseTree: `{ StringLiteral.new(value: yytext); })) |
|
|
|
.push(Action.new(parseTree: `{ StringLiteral.new(string: yytext); })) |
|
|
|
) |
|
|
|
.push(Sequence.new() |
|
|
|
.push(CharacterClass.new(value: '\"')) |
|
|
@ -541,7 +554,7 @@ rules.literal = Alternation.new() |
|
|
|
.push(End.new()) |
|
|
|
.push(CharacterClass.new(value: '\"')) |
|
|
|
.push(RuleCall.new(name: #ws)) |
|
|
|
.push(Action.new(parseTree: `{ StringLiteral.new(value: yytext); })) |
|
|
|
.push(Action.new(parseTree: `{ StringLiteral.new(string: yytext); })) |
|
|
|
); |
|
|
|
|
|
|
|
// class = '[' < ( !']' range )* > ']' - { newCharacterClass(yytext); } |
|
|
@ -578,10 +591,7 @@ rules.range = Alternation.new() |
|
|
|
rules.char = Alternation.new() |
|
|
|
.push(Sequence.new() |
|
|
|
.push(StringLiteral.new(string: "\\")) |
|
|
|
.push(Alternation.new() |
|
|
|
.push(CharacterClass.new(value: "abefnrtv\'[]\\")) |
|
|
|
.push(CharacterClass.new(value: '\"')) // I hate this |
|
|
|
) |
|
|
|
.push(CharacterClass.new(value: "abefnrtv\'\"[]\\")) |
|
|
|
) |
|
|
|
.push(Sequence.new() |
|
|
|
.push(StringLiteral.new(string: "\\")) |
|
|
@ -606,13 +616,13 @@ rules.action = Sequence.new() |
|
|
|
.push(RuleCall.new(name: #ws)) |
|
|
|
.push(Action.new(parseTree: `{ Action.new(parseTree: m); })); |
|
|
|
|
|
|
|
// metaStatement = b:metaBlock { newBlock(b); } |
|
|
|
// metaStatement = b:metaBlock { b; } |
|
|
|
// | e:metaExpression SEMI { e; } |
|
|
|
|
|
|
|
rules.metaStatement = Alternation.new() |
|
|
|
.push(Sequence.new() |
|
|
|
.push(Assignment.new(name: #b, rule: RuleCall.new(name: #metaBlock))) |
|
|
|
.push(Action.new(parseTree: `{ Block.new(b); })) |
|
|
|
.push(Action.new(parseTree: `{ b; })) |
|
|
|
) |
|
|
|
.push(Sequence.new() |
|
|
|
.push(Assignment.new(name: #e, rule: RuleCall.new(name: #metaExpression))) |
|
|
@ -651,7 +661,7 @@ rules.metaExpression = Alternation.new(id: 1234) |
|
|
|
.push(Assignment.new(name: #i, rule: RuleCall.new(name: #metaId))) |
|
|
|
.push(RuleCall.new(name: #assign)) |
|
|
|
.push(Assignment.new(name: #e, rule: RuleCall.new(name: #metaExpression))) |
|
|
|
.push(Action.new(parseTree: `{ SetVar.new(name: i, expr: e); })) |
|
|
|
.push(Action.new(parseTree: `{ SetVar.new(name: i, value: e); })) |
|
|
|
) |
|
|
|
.push(Sequence.new() |
|
|
|
.push(Assignment.new(name: #pf, rule: RuleCall.new(name: #metaPostfix))) |
|
|
@ -775,7 +785,7 @@ rules.metaBlock = Sequence.new() |
|
|
|
) |
|
|
|
) |
|
|
|
.push(RuleCall.new(name: #rbrace)) |
|
|
|
.push(Action.new(parseTree: `{ b; })); |
|
|
|
.push(Action.new(parseTree: `{ Block.new(body: b); })); |
|
|
|
|
|
|
|
// metaVar = i:metaId { newGetVar(i); } |
|
|
|
// metaId = < LETTER ALNUM* > - { intern(yytext); } |
|
|
@ -908,7 +918,6 @@ rules.ws = Star.new(expression: Alternation.new() |
|
|
|
// ----- Main ----- |
|
|
|
|
|
|
|
stream = newStream(readfile("rawgrammar.leg")); |
|
|
|
//stream = newStream("rule1 = rule2* | b:rule3 {a = b;} rule4 = 'hello' "); |
|
|
|
context = Context.new(outerContext: nil).init(); |
|
|
|
actions = []; |
|
|
|
|
|
|
@ -916,9 +925,24 @@ print("\nMatching : ", rules.grammar.match(stream, context, rules, actions), "\n |
|
|
|
|
|
|
|
// Execute all actions after all matching |
|
|
|
|
|
|
|
for (actionAndContext in actions) { |
|
|
|
//println(actionAndContext.action.parseTree); |
|
|
|
|
|
|
|
grammar = { for (actionAndContext in actions) { |
|
|
|
actionAndContext.action.execute(actionAndContext.context); |
|
|
|
} |
|
|
|
println(); |
|
|
|
}}; |
|
|
|
|
|
|
|
println(grammar); |
|
|
|
|
|
|
|
stream2 = newStream(readfile("rawgrammar.leg")); |
|
|
|
context2 = Context.new(outerContext: nil).init(); |
|
|
|
actions2 = []; |
|
|
|
|
|
|
|
print("\nMatching : ", grammar.grammar.match(stream2, context2, grammar, actions2), "\n"); |
|
|
|
|
|
|
|
grammar2 = { |
|
|
|
for (actionAndContext in actions2) { |
|
|
|
grammar2 = actionAndContext.action.execute(actionAndContext.context); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
println(grammar2); |
|
|
|
|