Bläddra i källkod

Make grammar_parser.meta use the entire grammar from minproto.leg

master
MaximeBarniaudy 11 månader sedan
förälder
incheckning
090142c69c
4 ändrade filer med 364 tillägg och 15 borttagningar
  1. +56
    -14
      grammar_parser.meta
  2. +46
    -0
      minproto.leg
  3. +7
    -1
      rawMetaGrammar.leg
  4. +255
    -0
      rawminproto.leg

+ 56
- 14
grammar_parser.meta Visa fil

@ -219,7 +219,7 @@ CharacterClass.match(stream, context, actions) {
// [a-] case
} else {
// println("[a-] case");
if (stream.peek() == ord('-')) {
if (stream.peek() == '-') {
success = 1;
}
}
@ -402,7 +402,7 @@ Action.execute(context) {
}
// Evaluate the parse tree and return to outer context if needed
returnValue = eval(self.parseTree, env: context.variables);
let returnValue = eval(self.parseTree, env: context.variables);
if (context.outerContext != nil) {
context.outerContext.variables[context.returnValueName] = returnValue;
}
@ -467,7 +467,10 @@ metaStatement = Alternation.new()
)
.push(Sequence.new()
.push(Assignment.new(name: #e, rule: RuleCall.new(name: #metaExpression)))
.push(RuleCall.new(name: #semi))
.push(Alternation.new()
.push(RuleCall.new(name: #semi))
.push(And.new(expression: RuleCall.new(name: #rbrace)))
)
.push(Action.new(parseTree: `{ e; }))
);
@ -568,6 +571,7 @@ mklist = Action.new(parseTree: `{ Object.new(); });
metaPrimary = Alternation.new()
.push(RuleCall.new(name: #nil))
.push(RuleCall.new(name: #number))
.push(RuleCall.new(name: #metaVar))
.push(RuleCall.new(name: #metaSubExpr));
@ -590,6 +594,29 @@ block = Sequence.new()
.push(RuleCall.new(name: #rbrace))
.push(Action.new(parseTree: `{ Block.new(body: b); }));
number = Alternation.new()
.push(Sequence.new()
.push(StringLiteral.new(string: "-"))
.push(Assignment.new(name: #n, rule: RuleCall.new(name: #unsign)))
.push(Action.new(parseTree: `{ Unyop.new(operation: __opNeg).push(n) }))
)
.push(Sequence.new()
.push(StringLiteral.new(string: "+"))
.push(Assignment.new(name: #n, rule: RuleCall.new(name: #number)))
.push(Action.new(parseTree: `{ n }))
)
.push(Sequence.new()
.push(Assignment.new(name: #n, rule: RuleCall.new(name: #unsign)))
.push(Action.new(parseTree: `{ n }))
);
unsign = Sequence.new()
.push(Begin.new())
.push(Plus.new(expression: RuleCall.new(name: #digit)))
.push(End.new())
.push(RuleCall.new(name: #ws))
.push(Action.new(parseTree: `{ yytext.asInteger(10); }));
metaVar = Sequence.new()
.push(Assignment.new(name: #i, rule: RuleCall.new(name: #metaId)))
.push(Action.new(parseTree: `{ GetVar.new(name: i); }));
@ -668,7 +695,7 @@ 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: `{ set(d.name, d.expression); }))
.push(Action.new(parseTree: `{ set(d.name, d.expression); print("Parsed rule ", d.name, "\n"); }))
))
.push(RuleCall.new(name: #end_of_file));
@ -823,14 +850,14 @@ literal = Alternation.new()
.push(Action.new(parseTree: `{ StringLiteral.new(string: yytext); }))
)
.push(Sequence.new()
.push(CharacterClass.new(value: 9;\"';))
.push(CharacterClass.new(value: 4;\"";))
.push(Begin.new())
.push(Star.new(expression: Sequence.new()
.push(Not.new(expression: CharacterClass.new(value: 9;\"';)))
.push(Not.new(expression: CharacterClass.new(value: 4;\"";)))
.push(RuleCall.new(name: #char))
))
.push(End.new())
.push(CharacterClass.new(value: 9;\"';))
.push(CharacterClass.new(value: 4;\"";))
.push(RuleCall.new(name: #ws))
.push(Action.new(parseTree: `{ StringLiteral.new(string: yytext); }))
);
@ -936,24 +963,39 @@ ws = Star.new(expression: Alternation.new()
with(#reading);
stream = newStream(readfile("rawMetaGrammar.leg"));
stream = newStream(readfile("rawminproto.leg"));
context = Context.new(outerContext: nil).init();
actions = [];
print("Matching : ", grammar.match(stream, context, actions), "\n");
grammar.match(stream, context, actions);
// 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("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);
without(#reading);
with(#reading);
@ -984,7 +1026,7 @@ with(#metaLanguage);
with(#peg);
with(#reading);
stream2 = newStream(readfile("rawMetaGrammar.leg"));
stream2 = newStream(readfile("rawminproto.leg"));
//stream2 = newStream("a = b:c::d { print(a[b].c); }");
context2 = Context.new(outerContext: nil).init();
actions2 = [];

+ 46
- 0
minproto.leg Visa fil

@ -3957,6 +3957,22 @@ oop prim_Object_initialise(oop func, oop self, oop args, oop env)
return self;
}
oop prim_newBinop(oop func, oop self, oop args, oop env)
{ assert(is(Object, args));
int argc = _get(args, Object,isize);
if (argc != 3) fatal("newBinop: Expected 3 arguments, got %d\n", argc);
oop *indexed = _get(args, Object,indexed);
return newBinop(integerValue(indexed[0], "prim_newBinop"), indexed[1], indexed[2]);
}
oop prim_newApply(oop func, oop self, oop args, oop env)
{ assert(is(Object, args));
int argc = _get(args, Object,isize);
if (argc != 2) fatal("newApply: Expected 2 arguments, got %d\n", argc);
oop *indexed = _get(args, Object,indexed);
return newApply(indexed[0], indexed[1]);
}
oop prim_Object_push(oop func, oop self, oop args, oop env)
{ assert(is(Object, args));
int argc = _get(args, Object,isize); assert(is(Object, self));
@ -5239,6 +5255,20 @@ oop prim_match(oop func, oop self, oop args, oop env)
#endif // PEGVM
oop prim_lvalue(oop func, oop self, oop args, oop env)
{ assert(is(Object, args));
int argc = _get(args, Object,isize);
if (argc != 1) fatal("lvalue: one argument expected\n");
return lvalue(_get(args, Object,indexed)[0]);
}
oop prim_assign(oop func, oop self, oop args, oop env)
{ assert(is(Object, args));
int argc = _get(args, Object,isize);
if (argc != 2) fatal("assign: 2 arguments expected\n");
return assign(_get(args, Object,indexed)[0], _get(args, Object,indexed)[1]);
}
oop replFile(FILE *in)
{
int oldline = lineno;
@ -5364,6 +5394,18 @@ int main(int argc, char **argv)
Object_put(pObject, prop_eval, newPrimitive(prim___eval__, newString("Object.__eval__"))); // inherited by all objects
#define stringify(x) #x
#define declareOp(NAME, OP) _set(intern(stringify(__op##NAME)), Symbol,value, newInteger(op##NAME));
doBinops(declareOp)
#undef declareOp
#define declareOp(NAME, OP) _set(intern(stringify(__##NAME)), Symbol,value, newInteger(NAME));
doUnyops(declareOp)
#undef declareOp
#undef stringify
#if TYPECODES
# define defineEvaluator(NAME) \
@ -5410,6 +5452,10 @@ int main(int argc, char **argv)
prim(__extern__ , prim_extern);
prim(__match__ , prim_match);
prim(intern , prim_intern);
prim(newBinop , prim_newBinop);
prim(newApply , prim_newApply);
prim(lvalue , prim_lvalue);
prim(assign , prim_assign);
# undef prim

+ 7
- 1
rawMetaGrammar.leg Visa fil

@ -28,7 +28,7 @@ args = LPAREN a:mklist
mklist = { Object.new(); }
primary = nil | var | subExpr
primary = nil | number | var | subExpr
subExpr = LPAREN e:expression RPAREN { e; }
@ -38,6 +38,12 @@ block = LBRACE b:mklist
nil = NIL { nil; }
number = "-" n:unsign { Unyop.new(operation: __opNeg).push(n) }
| "+" n:number { n }
| n:unsign { n }
unsign = < DIGIT+ > - { yytext.asInteger(10); }
var = i:id { GetVar.new(name: i); }
id = < LETTER ALNUM* > - { intern(yytext); }

+ 255
- 0
rawminproto.leg Visa fil

@ -0,0 +1,255 @@
start = - ( s:stmt # { yysval = s }
| !. # { yysval = 0 }
| < (!EOL .)* > # { fatal("syntax error near: %s", yytext) }
)
stmt = LET l:mklet k:id ASSIGN v:expr { l.keyvals.push(k); l.keyvals.push(v) }
( COMMA k:id ASSIGN v:expr { l.keyvals.push(k); l.keyvals.push(v) }
)* SEMI { l }
| WHILE LPAREN c:expr RPAREN s:stmt { While.new(condition: c, body: s) }
| IF LPAREN c:expr RPAREN s:stmt
( ELSE t:stmt { If.new(condition: c, consequent: s, alternate: t ) }
| { If.new(condition: c, consequent: s, alternate: nil) }
)
| CONT EOS { Continue.new() }
| BREAK e:expr EOS { Break.new(value: e) }
| BREAK EOS { Break.new(value: nil) }
| RETURN e:expr EOS { Return.new(value: e) }
| RETURN EOS { Return.new(value: nil) }
| FOR LPAREN i:id IN e:expr RPAREN
s:stmt { ForIn.new(identifier: i, expression: e, body: s) }
| FOR LPAREN i:id FROM a:expr
TO b:expr RPAREN s:stmt { ForFromTo.new(identifier: i, first: a, last: b, body: s) }
| FOR LPAREN i:expr SEMI c:expr SEMI
u:expr RPAREN s:stmt { For.new(initialise: i, condition: c, update: u, body: s) }
| i:id p:params b:block { SetVar.new(name: i, value: Lambda.new(parameters: p, body: b)) }
| v:proto DOT i:id p:params b:block { SetProp.new(object: v, key: i, value: Lambda.new(parameters: p, body: b)) }
| v:proto CCOLON i:id p:params b:block { SetProp.new(object: v, key: i, value: Lambda.new(parameters: p, body: b)) }
| b:block { Block.new(body: b) }
| e:expr EOS { e }
mklet = { Let.new() }
proto = v:var ( DOT j:id !LPAREN { v = GetProp.new(object: v, key: j) }
)* { v }
EOS = SEMI+ | &RBRACE | &ELSE
expr = i:id ASSIGN e:expr { SetVar.new(name: i, value: e) }
| l:logor ( ASSIGN r:expr { l = assign(l, r) }
| PLUSEQ r:expr { l = newBinop(__opPreAdd, lvalue(l), r) }
| MINUSEQ r:expr { l = newBinop(__opPreSub, lvalue(l), r) }
| STAREQ r:expr { l = newBinop(__opPreMul, lvalue(l), r) }
| SLASHEQ r:expr { l = newBinop(__opPreDiv, lvalue(l), r) }
| PCENTEQ r:expr { l = newBinop(__opPreMod, lvalue(l), r) }
| SHLEQ r:expr { l = newBinop(__opPreShl, lvalue(l), r) }
| SHREQ r:expr { l = newBinop(__opPreShr, lvalue(l), r) }
| ANDEQ r:expr { l = newBinop(__opPreAnd, lvalue(l), r) }
| XOREQ r:expr { l = newBinop(__opPreXor, lvalue(l), r) }
| OREQ r:expr { l = newBinop(__opPreOr, lvalue(l), r) }
)? { l }
logor = l:logand ( BARBAR r:logand { l = newBinop(__opLogOr, l, r) }
)* { l }
logand = l:bitor ( ANDAND r:bitor { l = newBinop(__opLogAnd, l, r) }
)* { l }
bitor = l:bitxor ( OR r:bitxor { l = newBinop(__opBitOr, l, r) }
)* { l }
bitxor = l:bitand ( XOR r:bitand { l = newBinop(__opBitXor, l, r) }
)* { l }
bitand = l:eq ( AND r:eq { l = newBinop(__opBitAnd, l, r) }
)* { l }
eq = l:ineq ( EQ r:ineq { l = newBinop(__opEq, l, r) }
| NOTEQ r:ineq { l = newBinop(__opNotEq, l, r) }
)* { l }
ineq = l:shift ( LESS r:shift { l = newBinop(__opLess, l, r) }
| LESSEQ r:shift { l = newBinop(__opLessEq, l, r) }
| GRTREQ r:shift { l = newBinop(__opGrtrEq, l, r) }
| GRTR r:shift { l = newBinop(__opGrtr, l, r) }
)* { l }
shift = l:sum ( SHL r:sum { l = newBinop(__opShl, l, r) }
| SHR r:sum { l = newBinop(__opShr, l, r) }
)* { l }
sum = l:prod ( PLUS r:prod { l = newBinop(__opAdd, l, r) }
| MINUS r:prod { l = newBinop(__opSub, l, r) }
)* { l }
prod = l:range ( STAR r:range { l = newBinop(__opMul, l, r) }
| SLASH r:range { l = newBinop(__opDiv, l, r) }
| PCENT r:range { l = newBinop(__opMod, l, r) }
) * { l }
range = i1:prefix ( DOTDOT i2:prefix { i1 = Range.new(start: i1, end: i2) }
) ? { i1 }
prefix = PPLUS p:prefix { newBinop(__opPreAdd, lvalue(p), 1) }
| MMINUS p:prefix { newBinop(__opPreSub, lvalue(p), 1) }
| PLING p:prefix { Unyop.new(operation: __opNot).push(p) }
| MINUS p:prefix { Unyop.new(operation: __opNeg).push(p) }
| TILDE p:prefix { Unyop.new(operation: __opCom).push(p) }
| BQUOTE s:stmt { Unyop.new(operation: __opQuasiquote).push(s) }
| COMMAT e:expr { Unyop.new(operation: __opUnquote).push(e) }
| postfix
postfix = p:primary
( LBRAK e:expr RBRAK { p = GetArray.new(object: p, index: e) }
| DOT i:id ( a:args !LBRACE { p = Invoke.new(self: p, method: i, arguments: a) }
| { p = GetProp.new(object: p, key: i) }
)
| a:args !LBRACE { p = newApply(p, a) }
| CCOLON i:id { p = GetProp.new(object: p, key: i) }
)*
( PPLUS { p = newBinop(__opPostAdd, lvalue(p), 1) }
| MMINUS { p = newBinop(__opPostAdd, lvalue(p), -1) }
)? { p }
args = LPAREN a:mkobj
( RPAREN
| ( k:id COLON e:expr { a[k] = e }
| e:expr { a.push(e) }
)
( COMMA ( k:id COLON e:expr { a[k] = e }
| e:expr { a.push(e) }
) )* RPAREN ) { a }
params = LPAREN p:mkobj
( RPAREN
| i:id ( COLON e:expr { p[i] = e }
| { p.push(i) }
)
( COMMA i:id ( COLON e:expr { p[i] = e }
| { p.push(i) }
)
)* RPAREN ) { p }
mkobj = { Object.new() }
primary = nil | number | string | symbol | var | lambda | subexpr | literal
lambda = p:params b:block { Lambda.new(parameters: p, body: b) }
subexpr = LPAREN e:expr RPAREN { e }
| b:block { Block.new(body: b) }
literal = LBRAK o:mkobj
( RBRAK
| ( ( i:id COLON e:expr { o[i] = e }
| e:expr { o.push(e) }
) ( COMMA ( i:id COLON e:expr { o[i] = e }
| e:expr { o.push(e) }
) )* )? RBRAK ) { Literal.new(object: o) }
block = LBRACE b:mkobj
( e:stmt { b.push(e) }
)* RBRACE { Block.new(body: b) }
nil = NIL { nil }
number = "-" n:unsign { Unyop.new(operation: __opNeg).push(n) }
| "+" n:number { n }
| n:unsign { n }
unsign = < DIGIT* '.' DIGIT+ EXP? > - { yytext.asFloat() }
| "0" [bB] < BIGIT+ > - { yytext.asInteger(2) }
| "0" [xX] < HIGIT+ > - { yytext.asInteger(16) }
| "0" < OIGIT* > - { yytext.asInteger(8) }
| < DIGIT+ > - { yytext.asInteger() }
string = '"' < ( !'"' char )* > '"' - { yytext.unescaped() }
| "'" < ( !"'" char )* > "'" - { yytext.unescaped() }
char = "\\" ( ["'\\abfnrtv]
| [xX] HIGIT*
| [0-7][0-7]?[0-7]?
)
| .
symbol = HASH i:id { i }
var = i:id { GetVar.new(name: i) }
id = < LETTER ALNUM* > - { intern(yytext) }
BIGIT = [0-1]
OIGIT = [0-7]
DIGIT = [0-9]
HIGIT = [0-9A-Fa-f]
LETTER = [A-Za-z_]
ALNUM = LETTER | DIGIT
SIGN = [-+]
EXP = [eE] SIGN DIGIT+
- = SPACE*
SPACE = [ \t] | EOL | '//' (!EOL .)*
EOL = [\n\r] # { ++lineno }
NIL = "nil" !ALNUM -
WHILE = "while" !ALNUM -
IF = "if" !ALNUM -
ELSE = "else" !ALNUM -
FOR = "for" !ALNUM -
IN = "in" !ALNUM -
FROM = "from" !ALNUM -
TO = "to" !ALNUM -
LET = "let" !ALNUM -
CONT = "continue" !ALNUM -
BREAK = "break" !ALNUM -
RETURN = "return" !ALNUM -
BQUOTE = "`" -
COMMAT = "@" -
HASH = "#" -
SEMI = ";" -
ASSIGN = "=" ![=] -
COMMA = "," -
COLON = ":" ![:] -
CCOLON = "::" -
LPAREN = "(" -
RPAREN = ")" -
LBRAK = "[" -
RBRAK = "]" -
LBRACE = "{" -
RBRACE = "}" -
BARBAR = "||" ![=] -
ANDAND = "&&" ![=] -
OR = "|" ![|=] -
OREQ = "|=" -
XOR = "^" ![=] -
XOREQ = "^=" -
AND = "&" ![&=] -
ANDEQ = "&=" -
EQ = "==" -
NOTEQ = "!=" -
LESS = "<" ![<=] -
LESSEQ = "<=" -
GRTREQ = ">=" -
GRTR = ">" ![=] -
SHL = "<<" ![=] -
SHLEQ = "<<=" -
SHR = ">>" ![=] -
SHREQ = ">>=" -
PLUS = "+" ![+=] -
PLUSEQ = "+=" -
PPLUS = "++" -
MINUS = "-" ![-=] -
MINUSEQ = "-=" -
MMINUS = "--" -
STAR = "*" ![=] -
STAREQ = "*=" -
SLASH = "/" ![/=] -
SLASHEQ = "/=" -
PCENT = "%" ![=] -
PCENTEQ = "%=" -
DOT = "." ![.] -
DOTDOT = ".." -
PLING = "!" ![=] -
TILDE = "~" -

Laddar…
Avbryt
Spara