Mercurial > projects > dil
diff trunk/src/Parser.d @ 242:7ec7ad8df9da
- Changed type of member tok in class BinaryExpression to Token*.
- Added method set() to Parser.
- Classes Parameter and Parameters inherit from Node now.
- Added member stcTok to Parameter. Changed constructor accordingly.
- Added member Other to enum NodeType.
- Added local variable 'begin' to many parse functions. Also calling the set() method to set the begin and end token for the parsed object.
- Fix: in some cases parsing AAs would cause getting caught in an infinite loop.
author | aziz |
---|---|
date | Wed, 01 Aug 2007 10:12:01 +0000 |
parents | deab661906ae |
children | 461e544ebb53 |
line wrap: on
line diff
--- a/trunk/src/Parser.d Tue Jul 31 14:09:03 2007 +0000 +++ b/trunk/src/Parser.d Wed Aug 01 10:12:01 2007 +0000 @@ -4,6 +4,7 @@ +/ module Parser; import Lexer; +import SyntaxTree; import Token; import Messages; import Information; @@ -89,6 +90,12 @@ return result; } + Class set(Class)(Class node, Token* begin) + { + node.setTokens(begin, this.token); + return node; + } + TOK peekNext() { Token* next = token; @@ -1880,15 +1887,16 @@ require(T.LParen); while (1) { - StorageClass stc; + auto paramBegin = token; + Token* stcTok; Type type; string ident; switch (token.type) { case T.Ref, T.Inout: + stcTok = token; nT(); - stc = StorageClass.Ref; // fall through case T.Identifier: auto next = peekNext(); @@ -1903,7 +1911,7 @@ type = parseDeclarator(ident); } - params ~= new Parameter(stc, type, ident, null); + params ~= set(new Parameter(stcTok, type, ident, null), paramBegin); if (token.type != T.Comma) break; @@ -2070,7 +2078,7 @@ nT(); string ident; auto type = parseDeclarator(ident); - param = new Parameter(StorageClass.None, type, ident, null); + param = new Parameter(null, type, ident, null); require(T.RParen); } catchBodies ~= new CatchBody(param, parseNoScopeStatement()); @@ -2336,11 +2344,13 @@ Expression parseExpression() { + auto begin = token; auto e = parseAssignExpression(); while (token.type == T.Comma) { nT(); e = new CommaExpression(e, parseAssignExpression()); + set(e, begin); } // if (!trying) // writef("§%s§", e.classinfo.name); @@ -2349,9 +2359,11 @@ Expression parseAssignExpression() { + typeof(token) begin; auto e = parseCondExpression(); while (1) { + begin = token; switch (token.type) { case T.Assign: @@ -2396,12 +2408,14 @@ default: return e; } + set(e, begin); } return e; } Expression parseCondExpression() { + auto begin = token; auto e = parseOrOrExpression(); if (token.type == T.Question) { @@ -2410,76 +2424,88 @@ require(T.Colon); auto iffalse = parseCondExpression(); e = new CondExpression(e, iftrue, iffalse); + set(e, begin); } return e; } Expression parseOrOrExpression() { + auto begin = token; alias parseAndAndExpression parseNext; auto e = parseNext(); while (token.type == T.OrLogical) { nT(); e = new OrOrExpression(e, parseNext()); + set(e, begin); } return e; } Expression parseAndAndExpression() { + auto begin = token; alias parseOrExpression parseNext; auto e = parseNext(); while (token.type == T.AndLogical) { nT(); e = new AndAndExpression(e, parseNext()); + set(e, begin); } return e; } Expression parseOrExpression() { + auto begin = token; alias parseXorExpression parseNext; auto e = parseNext(); while (token.type == T.OrBinary) { nT(); e = new OrExpression(e, parseNext()); + set(e, begin); } return e; } Expression parseXorExpression() { + auto begin = token; alias parseAndExpression parseNext; auto e = parseNext(); while (token.type == T.Xor) { nT(); e = new XorExpression(e, parseNext()); + set(e, begin); } return e; } Expression parseAndExpression() { + auto begin = token; alias parseCmpExpression parseNext; auto e = parseNext(); while (token.type == T.AndBinary) { nT(); e = new AndExpression(e, parseNext()); + set(e, begin); } return e; } Expression parseCmpExpression() { + auto begin = token; auto e = parseShiftExpression(); - TOK operator = token.type; - switch (operator) + auto operator = token; + switch (operator.type) { case T.Equal, T.NotEqual: nT(); @@ -2489,11 +2515,8 @@ if (peekNext() != T.Is) break; nT(); - operator = T.NotIdentity; - goto LNotIdentity; + // fall through case T.Is: - operator = T.Identity; - LNotIdentity: nT(); e = new IdentityExpression(e, parseShiftExpression(), operator); break; @@ -2508,63 +2531,75 @@ e = new InExpression(e, parseShiftExpression(), operator); break; default: + return e; } + set(e, begin); return e; } Expression parseShiftExpression() { + auto begin = token; auto e = parseAddExpression(); while (1) { - switch (token.type) + auto operator = token; + switch (operator.type) { - case T.LShift: nT(); e = new LShiftExpression(e, parseAddExpression()); break; - case T.RShift: nT(); e = new RShiftExpression(e, parseAddExpression()); break; - case T.URShift: nT(); e = new URShiftExpression(e, parseAddExpression()); break; + case T.LShift: nT(); e = new LShiftExpression(e, parseAddExpression(), operator); break; + case T.RShift: nT(); e = new RShiftExpression(e, parseAddExpression(), operator); break; + case T.URShift: nT(); e = new URShiftExpression(e, parseAddExpression(), operator); break; default: return e; } + set(e, begin); } assert(0); } Expression parseAddExpression() { + auto begin = token; auto e = parseMulExpression(); while (1) { - switch (token.type) + auto operator = token; + switch (operator.type) { - case T.Plus: nT(); e = new PlusExpression(e, parseMulExpression()); break; - case T.Minus: nT(); e = new MinusExpression(e, parseMulExpression()); break; - case T.Tilde: nT(); e = new CatExpression(e, parseMulExpression()); break; + case T.Plus: nT(); e = new PlusExpression(e, parseMulExpression(), operator); break; + case T.Minus: nT(); e = new MinusExpression(e, parseMulExpression(), operator); break; + case T.Tilde: nT(); e = new CatExpression(e, parseMulExpression(), operator); break; default: return e; } + set(e, begin); } assert(0); } Expression parseMulExpression() { + auto begin = token; auto e = parseUnaryExpression(); while (1) { - switch (token.type) + auto operator = token; + switch (operator.type) { - case T.Mul: nT(); e = new MulExpression(e, parseUnaryExpression()); break; - case T.Div: nT(); e = new DivExpression(e, parseUnaryExpression()); break; - case T.Mod: nT(); e = new ModExpression(e, parseUnaryExpression()); break; + case T.Mul: nT(); e = new MulExpression(e, parseUnaryExpression(), operator); break; + case T.Div: nT(); e = new DivExpression(e, parseUnaryExpression(), operator); break; + case T.Mod: nT(); e = new ModExpression(e, parseUnaryExpression(), operator); break; default: return e; } + set(e, begin); } assert(0); } Expression parseUnaryExpression() { + auto begin = token; Expression e; switch (token.type) { @@ -2582,7 +2617,7 @@ break; case T.Minus: case T.Plus: - nT(); e = new SignExpression(parseUnaryExpression(), token.type); + nT(); e = new SignExpression(parseUnaryExpression()); break; case T.Not: nT(); e = new NotExpression(parseUnaryExpression()); @@ -2592,10 +2627,9 @@ break; case T.New: e = parseNewExpression(); - break; + return e; case T.Delete: - nT(); - e = new DeleteExpression(parseUnaryExpression()); + nT(); e = new DeleteExpression(parseUnaryExpression()); break; case T.Cast: requireNext(T.LParen); @@ -2617,6 +2651,7 @@ auto type = try_(parseType_(), success); if (success) { + // TODO: save Token instead of string string ident = requireIdentifier(); e = new TypeDotIdExpression(type, ident); break; @@ -2624,16 +2659,19 @@ goto default; default: e = parsePostExpression(parsePrimaryExpression()); - break; + return e; } assert(e !is null); + set(e, begin); return e; } Expression parsePostExpression(Expression e) { + typeof(token) begin; while (1) { + begin = token; switch (token.type) { /* @@ -2663,7 +2701,7 @@ */ case T.Dot: e = new PostDotListExpression(e, parseDotListExpression()); - continue; + goto Lset; case T.PlusPlus: e = new PostIncrExpression(e); break; @@ -2672,7 +2710,7 @@ break; case T.LParen: e = new CallExpression(e, parseArguments(T.RParen)); - continue; + goto Lset; case T.LBracket: // parse Slice- and IndexExpression nT(); @@ -2689,7 +2727,7 @@ nT(); e = new SliceExpression(e, es[0], parseAssignExpression()); require(T.RBracket); - continue; + goto Lset; } else if (token.type == T.Comma) { @@ -2699,17 +2737,20 @@ require(T.RBracket); e = new IndexExpression(e, es); - continue; + goto Lset; default: return e; } nT(); + Lset: + set(e, begin); } assert(0); } Expression parsePrimaryExpression() { + auto begin = token; Expression e; switch (token.type) { @@ -2747,8 +2788,8 @@ e = new NullExpression(); break; case T.True, T.False: - e = new BoolExpression(token.type == T.True ? true : false); nT(); + e = new BoolExpression(); break; case T.Dollar: nT(); @@ -2764,11 +2805,10 @@ nT(); break; case T.CharLiteral, T.WCharLiteral, T.DCharLiteral: - e = new CharLiteralExpression(token.type); nT(); + e = new CharLiteralExpression(); break; case T.String: - // TODO: The Lexer doesn't allocate the tokens on the heap yet. So Token* will not work here. Token*[] stringLiterals; do { @@ -2808,35 +2848,25 @@ while (1) { keys ~= parseAssignExpression(); - if (token.type != T.Colon) - { - expected(T.Colon); - values ~= null; - if (token.type == T.RBracket) - break; - else - continue; - } + require(T.Colon); + values ~= parseAssignExpression(); + if (token.type != T.Comma) + break; nT(); - values ~= parseAssignExpression(); - if (token.type == T.RBracket) - break; - require(T.Comma); } } - assert(token.type == T.RBracket); - nT(); + require(T.RBracket); e = new AssocArrayLiteralExpression(keys, values); break; case T.LBrace: // DelegateLiteral := { Statements } - auto funcType = new FunctionType(null, Parameters.init); +// auto funcType = new FunctionType(null, Parameters.init); auto funcBody = parseFunctionBody(new FunctionBody); - e = new FunctionLiteralExpression(funcType, funcBody); + e = new FunctionLiteralExpression(null, funcBody); break; case T.Function, T.Delegate: // FunctionLiteral := (function|delegate) Type? '(' ArgumentList ')' '{' Statements '}' - TOK funcTok = token.type; +// TOK funcTok = token.type; nT(); // Skip function|delegate token. Type returnType; Parameters parameters; @@ -2848,7 +2878,7 @@ } auto funcType = new FunctionType(returnType, parameters); auto funcBody = parseFunctionBody(new FunctionBody); - e = new FunctionLiteralExpression(funcType, funcBody, funcTok); + e = new FunctionLiteralExpression(funcType, funcBody/+, funcTok+/); break; case T.Assert: Expression msg; @@ -2948,6 +2978,7 @@ nT(); e = parseExpression(); require(T.RParen); + // TODO: create ParenExpression? } break; // BasicType . Identifier @@ -2968,11 +2999,13 @@ error(MID.ExpectedButFound, "Expression", token.srcText); e = new EmptyExpression(); } + set(e, begin); return e; } Expression parseNewExpression(/*Expression e*/) { + auto begin = token; assert(token.type == T.New); nT(); // Skip new keyword. @@ -2993,7 +3026,7 @@ BaseClass[] bases = token.type != T.LBrace ? parseBaseClasses(false) : null ; auto decls = parseDeclarationDefinitionsBlock(); - return new NewAnonClassExpression(/*e, */newArguments, bases, ctorArguments, decls); + return set(new NewAnonClassExpression(/*e, */newArguments, bases, ctorArguments, decls), begin); } // NewExpression: @@ -3005,7 +3038,7 @@ { ctorArguments = parseArguments(T.RParen); } - return new NewExpression(/*e, */newArguments, type, ctorArguments); + return set(new NewExpression(/*e, */newArguments, type, ctorArguments), begin); } Type parseType() @@ -3015,6 +3048,7 @@ Type parseBasicType() { + auto begin = token; Type t; // IdentifierType tident; @@ -3028,6 +3062,7 @@ T.Cfloat, T.Cdouble, T.Creal, T.Void: t = new Type(token.type); nT(); + set(t, begin); break; /+ case T.Identifier, T.Dot: @@ -3056,18 +3091,24 @@ case T.Identifier, T.Typeof, T.Dot: t = parseDotListType(); break; + //case T.Const, T.Invariant: + // TODO: implement D 2.0 type constructors + //break; default: // TODO: issue error msg. error(MID.ExpectedButFound, "BasicType", token.srcText); t = new UndefinedType(); + set(t, begin); } return t; } Type parseBasicType2(Type t) { + typeof(token) begin; while (1) { + begin = token; switch (token.type) { case T.Mul: @@ -3076,7 +3117,7 @@ break; case T.LBracket: t = parseArrayType(t); - break; + continue; case T.Function, T.Delegate: TOK tok = token.type; nT(); @@ -3090,6 +3131,7 @@ default: return t; } + set(t, begin); } assert(0); } @@ -3160,6 +3202,7 @@ Type parseArrayType(Type t) { assert(token.type == T.LBracket); + auto begin = token; nT(); if (token.type == T.RBracket) { @@ -3184,6 +3227,7 @@ } require(T.RBracket); } + set(t, begin); return t; } @@ -3191,6 +3235,7 @@ { auto t = parseType(); + // TODO: change type of ident to Token* if (token.type == T.Identifier) { ident = token.identifier; @@ -3240,31 +3285,39 @@ } body { + auto begin = token; require(T.LParen); + auto params = new Parameters(); + if (token.type == T.RParen) { nT(); - return Parameters.init; + return set(params, begin); } - - Parameters params; - StorageClass stc; +// StorageClass stc; while (1) { - stc = StorageClass.In; + auto paramBegin = token; +// stc = StorageClass.In; + Token* stcTok; switch (token.type) { - case T.In: stc = StorageClass.In; nT(); goto default; + /+case T.In: stc = StorageClass.In; nT(); goto default; case T.Out: stc = StorageClass.Out; nT(); goto default; case T.Inout: case T.Ref: stc = StorageClass.Ref; nT(); goto default; - case T.Lazy: stc = StorageClass.Lazy; nT(); goto default; + case T.Lazy: stc = StorageClass.Lazy; nT(); goto default;+/ + // TODO: D 2.0 invariant/const/final/scope + case T.In, T.Out, T.Inout, T.Ref, T.Lazy: + stcTok = token; + nT(); + goto default; case T.Ellipses: nT(); - params ~= new Parameter(StorageClass.Variadic, null, null, null); - break; + params ~= set(new Parameter(stcTok, null, null, null), paramBegin); + break; // Exit loop. default: string ident; auto type = parseDeclarator(ident, true); @@ -3278,24 +3331,24 @@ if (token.type == T.Ellipses) { - stc |= StorageClass.Variadic; - params ~= new Parameter(stc, type, ident, assignExpr); + auto p = set(new Parameter(stcTok, type, ident, assignExpr), paramBegin); + p.stc |= StorageClass.Variadic; + params ~= p; nT(); - break; + break; // Exit loop. } - params ~= new Parameter(stc, type, ident, assignExpr); - if (token.type == T.Comma) - { - nT(); - continue; - } - break; + params ~= set(new Parameter(stcTok, type, ident, assignExpr), paramBegin); + + if (token.type != T.Comma) + break; // Exit loop. + nT(); + continue; } - break; + break; // Exit loop. } require(T.RParen); - return params; + return set(params, begin); } TemplateArguments parseTemplateArguments()