Mercurial > projects > dang
diff parser/Parser.d @ 99:857f0d530789 new_gen
Imports and improved module statement
Allow "module a.b.c"
Supports most forms of D's import.
import A, B;
import A, B = C;
import A, B : a = b, c;
author | Anders Halager <halager@gmail.com> |
---|---|
date | Tue, 06 May 2008 21:59:22 +0200 |
parents | 48bb2287c035 |
children | 5f258eaf9517 |
line wrap: on
line diff
--- a/parser/Parser.d Tue May 06 21:55:29 2008 +0200 +++ b/parser/Parser.d Tue May 06 21:59:22 2008 +0200 @@ -22,8 +22,6 @@ alias Object Decl; alias Object Module; -public: - this(MessageHandler messages) { this.messages = messages; @@ -35,31 +33,35 @@ this.lexer = lexer; this.action = act; - auto m = parseModule(); + Module m; + if (lexer.peek.type == Tok.Module) + { + Token _module = lexer.next; + ModuleName name = parseModuleName(); + m = action.actOnModule(_module, sm.getText(name.asRange())); + require(Tok.Seperator); + } + else + { + SLoc loc = lexer.peek.location; + m = action.actOnImplicitModule(loc, sm.getFile(loc)); + } - while(lexer.peek.type != Tok.EOF) - action.actOnModuleDecl(m, parseDecl()); + while (lexer.peek.type != Tok.EOF) + foreach (d; parseDeclDef()) + action.actOnModuleDecl(m, d); return m; } - Module parseModule() +private: + Decl[] parseDeclDef() { - if(lexer.peek.type == Tok.Module) - { - lexer.next; - if(lexer.peek.type != Tok.Identifier) - messages.report(UnexpectedTok, lexer.peek.location) - .arg(lexer.peek.type) - .arg(Tok.Identifier) - .fatal(ExitLevel.Parser); - - auto m = action.actOnModule(sm.getText(lexer.next.asRange)); - require(Tok.Seperator); - return m; - } - - return action.actOnModule(sm.getFile(lexer.peek.location)); + Token t = lexer.peek; + if (t.type == Tok.Import) + return parseImports(); + else + return [parseDecl()]; } Decl parseDecl() @@ -118,6 +120,83 @@ } /** + Parse a series of imports belonging to a single import token. + */ + Decl[] parseImports() + { + Token _import = require(Tok.Import); + SmallArray!(Decl) res; + void addToRes(Decl d) { res ~= d; } + + bool done = false; + while (!done && !on_a(Tok.Seperator)) + { + ModuleName mod = parseModuleName(); + Token tok = lexer.peek; + switch (tok.type) + { + case Tok.Comma: + // import A, B.C; + // parse another module-name + lexer.next(); + res ~= action.actOnImport(_import, mod, null); + break; + case Tok.Assign: + // import B = A.A; + // ^- must be a single identifier + // renamed import + if (mod.packages.length != 0) + { + SLoc loc = mod.packages[0].tok.location; + messages.report(RenameMustBeSingleIdent, loc); + } + //if (isStatic) + // error("Static imports cannot be renamed"); + lexer.next(); + Id name = mod.id; + mod = parseModuleName(); + // create from mod and rename to `name` + res ~= action.actOnImport(_import, mod, &name); + break; + case Tok.Colon: + // import A : a; + // selective imports, potentially import A : print = a + lexer.next(); + Decl d = action.actOnImport(_import, mod, null); + // do-while on a comma: + // add explicit symbol + do + { + Id sym = parseIdentifier(); + Id dummy; + Id* name = null; + if (skip(Tok.Assign)) + { + dummy = sym; + name = &dummy; + sym = parseIdentifier(); + } + action.addSelectiveImport(d, sym, name); + + } while (skip(Tok.Comma)); + require(Tok.Seperator); + res ~= d; + return res.safe(); + default: + goto Lerror; + } + res ~= action.actOnImport(_import, mod, null); + } + + require(Tok.Seperator); + return res.safe(); +Lerror: + while (!on_a (Tok.Seperator)) + lexer.next(); + return res.safe(); + } + + /** Parse struct */ Decl parseStruct(Id type, Id iden) @@ -152,6 +231,7 @@ return decl; } + /** Parse statements. @@ -237,14 +317,13 @@ return action.actOnExprStmt(exp); } - if ( n.isIdentifier()) + if (n.isIdentifier()) return action.actOnDeclStmt(parseVarDecl()); // Expression: a.b, a = b, a(b) etc. Exp exp = parseExpression(); require(Tok.Seperator); return action.actOnExprStmt(exp); - break; } case Tok.Switch: @@ -261,6 +340,7 @@ return action.actOnExprStmt(exp); } messages.report(UnexpectedBeginStmt, lexer.peek.location).arg(lexer.next.getType); + return null; } messages.report(UnexpectedTok, t.location); return null; @@ -332,8 +412,10 @@ return parseCompoundStatement(); return parseStatement(); } + /** - Parses a function-body or similar, expects { to be current token. + Parses a function-body or similar, expects an opening brace to be the + current token. Will consume both the starting { and ending } */ @@ -359,6 +441,28 @@ .arg(Tok.Identifier); } + ModuleName parseModuleName() + { + auto id = parseIdentifier(); + ModuleName mod; + while (skip(Tok.Dot)) + { + mod.packages ~= id; + if (lexer.peek.type != Tok.Identifier) { + messages.report(ExpectedIdAfterPackage, lexer.peek.location); + goto Lerror; + } + id = parseIdentifier(); + } + mod.id = id; + return mod; +Lerror: + while (!skip(Tok.Seperator)) + lexer.next(); + return mod; + } + + /** Parse a type - this includes pointer and array(at some point) types. */ @@ -609,6 +713,12 @@ return true; } + bool on_a(Tok t) + { + return lexer.peek.type == t; + } + Lexer lexer; SourceManager sm; } +