Package: ModuleReader

ModuleReader

nameinstructionbranchcomplexitylinemethod
ModuleReader(LexTokenReader)
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
getDefName(LexIdentifierToken, LexNameToken)
M: 2 C: 16
89%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 1 C: 2
67%
M: 0 C: 1
100%
ignoreTypeParams()
M: 0 C: 11
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
importAll(LexIdentifierToken)
M: 30 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
newType()
M: 0 C: 11
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
readDLModule()
M: 38 C: 100
72%
M: 6 C: 6
50%
M: 6 C: 1
14%
M: 7 C: 23
77%
M: 0 C: 1
100%
readExportedFunction()
M: 0 C: 26
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
readExportedFunctions()
M: 9 C: 37
80%
M: 4 C: 4
50%
M: 3 C: 2
40%
M: 1 C: 9
90%
M: 0 C: 1
100%
readExportedOperation()
M: 0 C: 22
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
readExportedOperations()
M: 7 C: 39
85%
M: 2 C: 6
75%
M: 2 C: 3
60%
M: 1 C: 9
90%
M: 0 C: 1
100%
readExportedType()
M: 0 C: 18
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
readExportedTypes()
M: 9 C: 40
82%
M: 4 C: 6
60%
M: 3 C: 3
50%
M: 1 C: 9
90%
M: 0 C: 1
100%
readExportedValue()
M: 0 C: 22
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
readExportedValues()
M: 9 C: 40
82%
M: 4 C: 6
60%
M: 3 C: 3
50%
M: 1 C: 9
90%
M: 0 C: 1
100%
readExports()
M: 0 C: 9
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
readExportsFromModule()
M: 0 C: 54
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 12
100%
M: 0 C: 1
100%
readExportsOfOneType()
M: 6 C: 31
84%
M: 1 C: 4
80%
M: 1 C: 4
80%
M: 2 C: 9
82%
M: 0 C: 1
100%
readFlatModule()
M: 0 C: 21
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
readIdList(boolean)
M: 0 C: 25
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
readImportDefinition()
M: 0 C: 15
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
readImportedFunction(LexIdentifierToken)
M: 0 C: 45
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 11
100%
M: 0 C: 1
100%
readImportedFunctions(LexIdentifierToken)
M: 9 C: 39
81%
M: 4 C: 4
50%
M: 3 C: 2
40%
M: 1 C: 9
90%
M: 0 C: 1
100%
readImportedOperation(LexIdentifierToken)
M: 0 C: 40
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 10
100%
M: 0 C: 1
100%
readImportedOperations(LexIdentifierToken)
M: 9 C: 39
81%
M: 4 C: 4
50%
M: 3 C: 2
40%
M: 1 C: 9
90%
M: 0 C: 1
100%
readImportedType(LexIdentifierToken)
M: 0 C: 64
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 19
100%
M: 0 C: 1
100%
readImportedTypes(LexIdentifierToken)
M: 9 C: 39
81%
M: 4 C: 4
50%
M: 3 C: 2
40%
M: 1 C: 9
90%
M: 0 C: 1
100%
readImportedValue(LexIdentifierToken)
M: 0 C: 38
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 10
100%
M: 0 C: 1
100%
readImportedValues(LexIdentifierToken)
M: 9 C: 39
81%
M: 4 C: 4
50%
M: 3 C: 2
40%
M: 1 C: 9
90%
M: 0 C: 1
100%
readImports(LexIdentifierToken)
M: 0 C: 28
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
readImportsFromModule(LexIdentifierToken)
M: 0 C: 55
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 12
100%
M: 0 C: 1
100%
readImportsOfOneType(LexIdentifierToken)
M: 6 C: 35
85%
M: 1 C: 4
80%
M: 1 C: 4
80%
M: 2 C: 9
82%
M: 0 C: 1
100%
readModule()
M: 50 C: 108
68%
M: 6 C: 14
70%
M: 5 C: 6
55%
M: 7 C: 26
79%
M: 0 C: 1
100%
readModules()
M: 30 C: 80
73%
M: 6 C: 10
63%
M: 5 C: 5
50%
M: 8 C: 22
73%
M: 0 C: 1
100%

Coverage

1: /*******************************************************************************
2: *
3: *        Copyright (c) 2008 Fujitsu Services Ltd.
4: *
5: *        Author: Nick Battle
6: *
7: *        This file is part of VDMJ.
8: *
9: *        VDMJ is free software: you can redistribute it and/or modify
10: *        it under the terms of the GNU General Public License as published by
11: *        the Free Software Foundation, either version 3 of the License, or
12: *        (at your option) any later version.
13: *
14: *        VDMJ is distributed in the hope that it will be useful,
15: *        but WITHOUT ANY WARRANTY; without even the implied warranty of
16: *        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17: *        GNU General Public License for more details.
18: *
19: *        You should have received a copy of the GNU General Public License
20: *        along with VDMJ. If not, see <http://www.gnu.org/licenses/>.
21: *
22: ******************************************************************************/
23:
24: package org.overture.parser.syntax;
25:
26: import java.io.File;
27: import java.util.List;
28: import java.util.Vector;
29:
30: import org.overture.ast.annotations.PAnnotation;
31: import org.overture.ast.definitions.ATypeDefinition;
32: import org.overture.ast.definitions.PDefinition;
33: import org.overture.ast.factory.AstFactory;
34: import org.overture.ast.intf.lex.ILexCommentList;
35: import org.overture.ast.intf.lex.ILexNameToken;
36: import org.overture.ast.lex.LexIdentifierToken;
37: import org.overture.ast.lex.LexLocation;
38: import org.overture.ast.lex.LexNameList;
39: import org.overture.ast.lex.LexNameToken;
40: import org.overture.ast.lex.LexToken;
41: import org.overture.ast.lex.VDMToken;
42: import org.overture.ast.modules.AFromModuleImports;
43: import org.overture.ast.modules.AFunctionExport;
44: import org.overture.ast.modules.AFunctionValueImport;
45: import org.overture.ast.modules.AModuleExports;
46: import org.overture.ast.modules.AModuleImports;
47: import org.overture.ast.modules.AModuleModules;
48: import org.overture.ast.modules.AOperationExport;
49: import org.overture.ast.modules.AOperationValueImport;
50: import org.overture.ast.modules.ATypeExport;
51: import org.overture.ast.modules.ATypeImport;
52: import org.overture.ast.modules.AValueExport;
53: import org.overture.ast.modules.PExport;
54: import org.overture.ast.modules.PImport;
55: import org.overture.ast.modules.SValueImport;
56: import org.overture.ast.types.PType;
57: import org.overture.ast.util.ClonableFile;
58: import org.overture.ast.util.modules.ModuleList;
59: import org.overture.config.Settings;
60: import org.overture.parser.lex.LexException;
61: import org.overture.parser.lex.LexTokenReader;
62: import org.overture.parser.messages.LocatedException;
63:
64: /**
65: * A syntax analyser to parse modules.
66: */
67:
68: public class ModuleReader extends SyntaxReader
69: {
70:         public ModuleReader(LexTokenReader reader)
71:         {
72:                 super(reader);
73:         }
74:
75:         public ModuleList readModules()
76:         {
77:                 ModuleList modules = new ModuleList();
78:
79:                 try
80:                 {
81:•                        if (lastToken().is(VDMToken.EOF))
82:                         {
83:                                 return modules; // The file is empty
84:                         }
85:
86:•                        if (lastToken().isNot(VDMToken.MODULE)
87:•                                        && !DefinitionReader.newSection(lastToken()))
88:                         {
89:                                 warning(5015, "LaTeX source should start with %comment, \\document, \\section or \\subsection", lastToken().location);
90:                         }
91:
92:•                        while (lastToken().isNot(VDMToken.EOF)
93:•                                        && lastToken().isNot(VDMToken.END))
94:                         {
95:•                                switch (lastToken().type)
96:                                 {
97:                                         case MODULE:
98:                                                 ILexCommentList comments = getComments();
99:                                                 List<PAnnotation> annotations = readAnnotations(comments);
100:                                                 beforeAnnotations(this, annotations);
101:                                                 AModuleModules module = readModule();
102:                                                 afterAnnotations(this, annotations, module);
103:                                                 module.setAnnotations(annotations);
104:                                                 module.setComments(comments);
105:                                                 modules.add(module);
106:                                                 break;
107:
108:                                         case DLMODULE:
109:                                                 modules.add(readDLModule());
110:                                                 break;
111:
112:                                         case IDENTIFIER:
113:                                                 LexIdentifierToken id = lastIdToken();
114:
115:•                                                if (id.getName().equals("class"))
116:                                                 {
117:                                                         throwMessage(2260, "Module starts with 'class' instead of 'module'");
118:                                                 }
119:                                                 // else fall through to a flat definition...
120:
121:                                         default:
122:                                                 modules.add(readFlatModule());
123:                                                 break;
124:                                 }
125:                         }
126:                 } catch (LocatedException e)
127:                 {
128:                         VDMToken[] end = new VDMToken[0];
129:                         report(e, end, end);
130:                 }
131:
132:                 return modules;
133:         }
134:
135:         public static AFromModuleImports importAll(LexIdentifierToken from)
136:         {
137:                 List<List<PImport>> types = new Vector<List<PImport>>();
138:                 LexNameToken all = new LexNameToken(from.getName(), "all", from.location);
139:                 List<PImport> impAll = new Vector<PImport>();
140:                 impAll.add(AstFactory.newAAllImport(all));
141:                 types.add(impAll);
142:                 return AstFactory.newAFromModuleImports(from, types);
143:         }
144:
145:         private AModuleModules readFlatModule() throws ParserException,
146:                         LexException
147:         {
148:                 File file = lastToken().location.getFile();
149:                 setCurrentModule("DEFAULT");
150:                 List<PDefinition> definitions = getDefinitionReader().readDefinitions();
151:                 checkFor(VDMToken.EOF, 2318, "Unexpected token after flat definitions");
152:                 return AstFactory.newAModuleModules(file, definitions);
153:         }
154:
155:         private AModuleModules readModule() throws ParserException, LexException
156:         {
157:                 LexIdentifierToken name = new LexIdentifierToken("?", false, lastToken().location);
158:                 AModuleImports imports = null;
159:                 AModuleExports exports = null;
160:
161:                 try
162:                 {
163:                         setCurrentModule("");
164:                         checkFor(VDMToken.MODULE, 2170, "Expecting 'module' at module start");
165:                         name = readIdToken("Expecting identifier after 'module'");
166:                         setCurrentModule(name.getName());
167:
168:•                        if (lastToken().is(VDMToken.IMPORTS))
169:                         {
170:                                 imports = readImports(name);
171:                         }
172:
173:•                        if (lastToken().is(VDMToken.EXPORTS))
174:                         {
175:                                 exports = readExports();
176:                         }
177:
178:                         // Be forgiving about the ordering...
179:
180:•                        if (imports == null && lastToken().is(VDMToken.IMPORTS))
181:                         {
182:•                                if (Settings.strict)
183:                                 {
184:                                         warning(5024, "Strict: order should be imports then exports", lastToken().location);
185:                                 }
186:                                 
187:                                 imports = readImports(name);
188:                         }
189:                         
190:•                        if (Settings.strict && exports == null)
191:                         {
192:                                 warning(5025, "Strict: expecting 'exports all' clause", lastToken().location);
193:                         }
194:                 }
195:                 catch (LocatedException e)
196:                 {
197:                         VDMToken[] after = { VDMToken.DEFINITIONS };
198:                         VDMToken[] upto = { VDMToken.END };
199:                         report(e, after, upto);
200:                 }
201:
202:                 List<PDefinition> defs = null;
203:
204:•                if (lastToken().is(VDMToken.DEFINITIONS))
205:                 {
206:                         nextToken();
207:                         defs = getDefinitionReader().readDefinitions();
208:                 } else
209:                 {
210:                         defs = new Vector<PDefinition>();
211:                 }
212:
213:                 checkFor(VDMToken.END, 2171, "Expecting 'end' after module definitions");
214:                 LexIdentifierToken endname = readIdToken("Expecting 'end <name>' after module definitions");
215:
216:•                if (name != null && !name.equals(endname))
217:                 {
218:                         throwMessage(2049, "Expecting 'end " + name.getName() + "'");
219:                 }
220:
221:                 LexLocation.addSpan(idToName(name), lastToken());
222:                 return AstFactory.newAModuleModules(name, imports, exports, defs);
223:         }
224:
225:         private AModuleModules readDLModule() throws ParserException, LexException
226:         {
227:                 LexIdentifierToken name = new LexIdentifierToken("?", false, lastToken().location);
228:                 // FIXME dlmodules not implemented
229:                 AModuleImports imports = null;
230:                 AModuleExports exports = null;
231:                 // LexStringToken library = null;
232:
233:                 try
234:                 {
235:                         checkFor(VDMToken.DLMODULE, 2172, "Expecting 'dlmodule' at module start");
236:                         name = readIdToken("Expecting identifier after 'dlmodule'");
237:                         setCurrentModule(name.getName());
238:
239:•                        if (lastToken().is(VDMToken.IMPORTS))
240:                         {
241:                                 imports = readImports(name);
242:                         }
243:
244:•                        if (lastToken().is(VDMToken.EXPORTS))
245:                         {
246:                                 exports = readExports();
247:                         }
248:
249:•                        if (lastToken().is(VDMToken.USELIB))
250:                         {
251:•                                if (nextToken().is(VDMToken.STRING))
252:                                 {
253:                                         /* library = (LexStringToken) */lastToken();
254:                                         nextToken();
255:                                 } else
256:                                 {
257:                                         throwMessage(2050, "Expecting library name after 'uselib'");
258:                                 }
259:                         }
260:                 } catch (LocatedException e)
261:                 {
262:                         VDMToken[] after = {};
263:                         VDMToken[] upto = { VDMToken.END };
264:                         report(e, after, upto);
265:                 }
266:
267:                 checkFor(VDMToken.END, 2173, "Expecting 'end' after dlmodule definitions");
268:                 LexIdentifierToken endname = readIdToken("Expecting 'end <name>' after dlmodule definitions");
269:
270:•                if (name != null && !name.equals(endname))
271:                 {
272:                         throwMessage(2051, "Expecting 'end " + name.getName() + "'");
273:                 }
274:
275:                 // return new DLModule(name, imports, exports, library);
276:                 List<ClonableFile> files = new Vector<ClonableFile>();
277:                 files.add(new ClonableFile(name.location.getFile()));
278:
279:                 AModuleModules module = AstFactory.newAModuleModules(name, imports, exports, null);
280:                 module.setFiles(files);
281:                 module.setIsDLModule(true);
282:                 return module;
283:         }
284:
285:         private AModuleExports readExports() throws ParserException, LexException
286:         {
287:                 checkFor(VDMToken.EXPORTS, 2174, "Malformed imports? Expecting 'exports' section");
288:                 return AstFactory.newAModuleExports(readExportsFromModule());
289:         }
290:
291:         private List<List<PExport>> readExportsFromModule() throws ParserException,
292:                         LexException
293:         {
294:                 List<List<PExport>> types = new Vector<List<PExport>>();
295:
296:•                if (lastToken().is(VDMToken.ALL))
297:                 {
298:                         LexNameToken all = new LexNameToken(getCurrentModule(), "all", lastToken().location);
299:                         List<PExport> expAll = new Vector<PExport>();
300:                         expAll.add(AstFactory.newAAllExport(all.location));
301:                         types.add(expAll);
302:                         nextToken();
303:                         return types;
304:                 }
305:
306:                 types.add(readExportsOfOneType());
307:
308:•                while (newType())
309:                 {
310:                         types.add(readExportsOfOneType());
311:                 }
312:
313:                 return types;
314:         }
315:
316:         private List<PExport> readExportsOfOneType() throws ParserException,
317:                         LexException
318:         {
319:•                switch (lastToken().type)
320:                 {
321:                         case TYPES:
322:                                 nextToken();
323:                                 return readExportedTypes();
324:
325:                         case VALUES:
326:                                 nextToken();
327:                                 return readExportedValues();
328:
329:                         case FUNCTIONS:
330:                                 nextToken();
331:                                 return readExportedFunctions();
332:
333:                         case OPERATIONS:
334:                                 nextToken();
335:                                 return readExportedOperations();
336:                                 
337:                         default:
338:                                 throwMessage(2052, "Expecting 'all', 'types', 'values', 'functions' or 'operations'");
339:                                 return null;
340:                 }
341:         }
342:
343:         private List<PExport> readExportedTypes() throws ParserException,
344:                         LexException
345:         {
346:                 List<PExport> list = new Vector<PExport>();
347:                 list.add(readExportedType());
348:                 boolean semi = ignore(VDMToken.SEMICOLON);
349:
350:•                while (lastToken().isNot(VDMToken.DEFINITIONS)
351:•                                && lastToken().isNot(VDMToken.USELIB) && !newType())
352:                 {
353:•                        if (!semi && Settings.strict)
354:                         {
355:                                 warning(5022, "Strict: expecting semi-colon between exports", lastToken().location);
356:                         }
357:
358:                         list.add(readExportedType());
359:                         semi = ignore(VDMToken.SEMICOLON);
360:                 }
361:
362:                 return list;
363:         }
364:
365:         private ATypeExport readExportedType() throws ParserException, LexException
366:         {
367:                 boolean struct = lastToken().is(VDMToken.STRUCT);
368:•                if (struct)
369:                 {
370:                         nextToken();
371:                 }
372:                 LexNameToken name = readNameToken("Expecting exported type name");
373:                 return AstFactory.newATypeExport(name, struct);
374:         }
375:
376:         private List<PExport> readExportedValues() throws ParserException,
377:                         LexException
378:         {
379:                 List<PExport> list = new Vector<PExport>();
380:                 list.add(readExportedValue());
381:                 boolean semi = ignore(VDMToken.SEMICOLON);
382:
383:•                while (lastToken().isNot(VDMToken.DEFINITIONS)
384:•                                && lastToken().isNot(VDMToken.USELIB) && !newType())
385:                 {
386:•                        if (!semi && Settings.strict)
387:                         {
388:                                 warning(5022, "Strict: expecting semi-colon between exports", lastToken().location);
389:                         }
390:
391:                         list.add(readExportedValue());
392:                         semi = ignore(VDMToken.SEMICOLON);
393:                 }
394:
395:                 return list;
396:         }
397:
398:         private AValueExport readExportedValue() throws ParserException,
399:                         LexException
400:         {
401:                 LexToken token = lastToken();
402:                 List<ILexNameToken> nameList = readIdList(false);
403:                 checkFor(VDMToken.COLON, 2175, "Expecting ':' after export name");
404:                 PType type = getTypeReader().readType();
405:                 return AstFactory.newAValueExport(token.location, nameList, type);
406:         }
407:
408:         private List<PExport> readExportedFunctions() throws ParserException,
409:                         LexException
410:         {
411:                 List<PExport> list = new Vector<PExport>();
412:                 list.add(readExportedFunction());
413:                 boolean semi = ignore(VDMToken.SEMICOLON);
414:
415:•                while (lastToken().is(VDMToken.IDENTIFIER)
416:•                                || lastToken().is(VDMToken.NAME))
417:                 {
418:•                        if (!semi && Settings.strict)
419:                         {
420:                                 warning(5022, "Strict: expecting semi-colon between exports", lastToken().location);
421:                         }
422:
423:                         list.add(readExportedFunction());
424:                         semi = ignore(VDMToken.SEMICOLON);
425:                 }
426:
427:                 return list;
428:         }
429:
430:         private AFunctionExport readExportedFunction() throws ParserException,
431:                         LexException
432:         {
433:                 LexToken token = lastToken();
434:                 List<ILexNameToken> nameList = readIdList(true);
435:                 List<ILexNameToken> typeParams = ignoreTypeParams();
436:                 checkFor(VDMToken.COLON, 2176, "Expecting ':' after export name");
437:                 PType type = getTypeReader().readType();
438:                 return AstFactory.newAFunctionExport(token.location, nameList, type, typeParams);
439:         }
440:
441:         private List<PExport> readExportedOperations() throws ParserException,
442:                         LexException
443:         {
444:                 List<PExport> list = new Vector<PExport>();
445:                 list.add(readExportedOperation());
446:                 boolean semi = ignore(VDMToken.SEMICOLON);
447:
448:•                while (lastToken().is(VDMToken.IDENTIFIER)
449:•                                || lastToken().is(VDMToken.NAME))
450:                 {
451:•                        if (!semi && Settings.strict)
452:                         {
453:                                 warning(5022, "Strict: expecting semi-colon between exports", lastToken().location);
454:                         }
455:
456:                         list.add(readExportedOperation());
457:                         semi = ignore(VDMToken.SEMICOLON);
458:                 }
459:
460:                 return list;
461:         }
462:
463:         private AOperationExport readExportedOperation() throws ParserException,
464:                         LexException
465:         {
466:                 LexToken token = lastToken();
467:                 List<ILexNameToken> nameList = readIdList(false);
468:                 checkFor(VDMToken.COLON, 2177, "Expecting ':' after export name");
469:                 PType type = getTypeReader().readOperationType();
470:                 return AstFactory.newAOperationExport(token.location, nameList, type);
471:         }
472:
473:         private List<ILexNameToken> readIdList(boolean reservedOK) throws ParserException,
474:                         LexException
475:         {
476:                 List<ILexNameToken> list = new Vector<ILexNameToken>();
477:                 list.add(readNameToken("Expecting name list", reservedOK));
478:
479:•                while (ignore(VDMToken.COMMA))
480:                 {
481:                         list.add(readNameToken("Expecting name list", reservedOK));
482:                 }
483:
484:                 return list;
485:         }
486:
487:         private AModuleImports readImports(LexIdentifierToken name)
488:                         throws ParserException, LexException
489:         {
490:                 checkFor(VDMToken.IMPORTS, 2178, "Expecting 'imports'");
491:                 List<AFromModuleImports> imports = new Vector<AFromModuleImports>();
492:                 imports.add(readImportDefinition());
493:
494:•                while (ignore(VDMToken.COMMA))
495:                 {
496:                         imports.add(readImportDefinition());
497:                 }
498:
499:                 return AstFactory.newAModuleImports(name, imports);
500:         }
501:
502:         private AFromModuleImports readImportDefinition() throws ParserException,
503:                         LexException
504:         {
505:                 checkFor(VDMToken.FROM, 2179, "Expecting 'from' in import definition");
506:                 LexIdentifierToken from = readIdToken("Expecting module identifier after 'from'");
507:                 return AstFactory.newAFromModuleImports(from, readImportsFromModule(from));
508:         }
509:
510:         private List<List<PImport>> readImportsFromModule(LexIdentifierToken from)
511:                         throws ParserException, LexException
512:         {
513:                 List<List<PImport>> types = new Vector<List<PImport>>();
514:
515:•                if (lastToken().is(VDMToken.ALL))
516:                 {
517:                         LexNameToken all = new LexNameToken(getCurrentModule(), "all", lastToken().location);
518:                         List<PImport> impAll = new Vector<PImport>();
519:                         impAll.add(AstFactory.newAAllImport(all));
520:                         types.add(impAll);
521:                         nextToken();
522:                         return types;
523:                 }
524:
525:                 types.add(readImportsOfOneType(from));
526:
527:•                while (newType())
528:                 {
529:                         types.add(readImportsOfOneType(from));
530:                 }
531:
532:                 return types;
533:         }
534:
535:         private List<PImport> readImportsOfOneType(LexIdentifierToken from)
536:                         throws ParserException, LexException
537:         {
538:•                switch (lastToken().type)
539:                 {
540:                         case TYPES:
541:                                 nextToken();
542:                                 return readImportedTypes(from);
543:
544:                         case VALUES:
545:                                 nextToken();
546:                                 return readImportedValues(from);
547:
548:                         case FUNCTIONS:
549:                                 nextToken();
550:                                 return readImportedFunctions(from);
551:
552:                         case OPERATIONS:
553:                                 nextToken();
554:                                 return readImportedOperations(from);
555:                                 
556:                         default:
557:                                 throwMessage(2054, "Expecting types, values, functions or operations");
558:                                 return null;
559:                 }
560:         }
561:
562:         private List<PImport> readImportedTypes(LexIdentifierToken from)
563:                         throws ParserException, LexException
564:         {
565:                 List<PImport> list = new Vector<PImport>();
566:                 list.add(readImportedType(from));
567:                 boolean semi = ignore(VDMToken.SEMICOLON);
568:
569:•                while (lastToken().is(VDMToken.IDENTIFIER)
570:•                                || lastToken().is(VDMToken.NAME))
571:                 {
572:•                        if (!semi && Settings.strict)
573:                         {
574:                                 warning(5023, "Strict: expecting semi-colon between imports", lastToken().location);
575:                         }
576:
577:                         list.add(readImportedType(from));
578:                         semi = ignore(VDMToken.SEMICOLON);
579:                 }
580:
581:                 return list;
582:         }
583:
584:         private ATypeImport readImportedType(LexIdentifierToken from)
585:                         throws ParserException, LexException
586:         {
587:                 String savedModule = getCurrentModule();
588:
589:                 try
590:                 {
591:                         reader.push();
592:                         setCurrentModule(from.getName()); // So names are from "from" in...
593:                         ATypeDefinition def = getDefinitionReader().readTypeDefinition();
594:                         setCurrentModule(savedModule); // and restore
595:                         reader.unpush();
596:
597:                         LexNameToken renamed = null;
598:
599:•                        if (ignore(VDMToken.RENAMED))
600:                         {
601:                                 renamed = readNameToken("Expected renamed type name");
602:                         }
603:
604:                         return AstFactory.newATypeImport(def, renamed);
605:                 } catch (ParserException e)
606:                 {
607:                         reader.pop();
608:                         setCurrentModule(savedModule);
609:                 }
610:
611:                 LexNameToken name = readNameToken("Expecting imported type name");
612:                 LexNameToken defname = getDefName(from, name);
613:                 LexNameToken renamed = null;
614:
615:•                if (ignore(VDMToken.RENAMED))
616:                 {
617:                         renamed = readNameToken("Expected renamed type name");
618:                 }
619:
620:                 return AstFactory.newATypeImport(defname, renamed);
621:         }
622:
623:         private List<PImport> readImportedValues(LexIdentifierToken from)
624:                         throws ParserException, LexException
625:         {
626:                 List<PImport> list = new Vector<PImport>();
627:                 list.add(readImportedValue(from));
628:                 boolean semi = ignore(VDMToken.SEMICOLON);
629:
630:•                while (lastToken().is(VDMToken.IDENTIFIER)
631:•                                || lastToken().is(VDMToken.NAME))
632:                 {
633:•                        if (!semi && Settings.strict)
634:                         {
635:                                 warning(5023, "Strict: expecting semi-colon between imports", lastToken().location);
636:                         }
637:
638:                         list.add(readImportedValue(from));
639:                         semi = ignore(VDMToken.SEMICOLON);
640:                 }
641:
642:                 return list;
643:         }
644:
645:         private SValueImport readImportedValue(LexIdentifierToken from)
646:                         throws ParserException, LexException
647:         {
648:                 LexNameToken name = readNameToken("Expecting imported value name");
649:                 LexNameToken defname = getDefName(from, name);
650:                 PType type = null;
651:
652:•                if (lastToken().is(VDMToken.COLON))
653:                 {
654:                         nextToken();
655:                         type = getTypeReader().readType();
656:                 }
657:
658:                 LexNameToken renamed = null;
659:
660:•                if (ignore(VDMToken.RENAMED))
661:                 {
662:                         renamed = readNameToken("Expected renamed value name");
663:                 }
664:
665:                 return AstFactory.newAValueValueImport(defname, type, renamed);
666:         }
667:
668:         private List<PImport> readImportedFunctions(LexIdentifierToken from)
669:                         throws ParserException, LexException
670:         {
671:                 List<PImport> list = new Vector<PImport>();
672:                 list.add(readImportedFunction(from));
673:                 boolean semi = ignore(VDMToken.SEMICOLON);
674:
675:•                while (lastToken().is(VDMToken.IDENTIFIER)
676:•                                || lastToken().is(VDMToken.NAME))
677:                 {
678:•                        if (!semi && Settings.strict)
679:                         {
680:                                 warning(5023, "Strict: expecting semi-colon between imports", lastToken().location);
681:                         }
682:
683:                         list.add(readImportedFunction(from));
684:                         semi = ignore(VDMToken.SEMICOLON);
685:                 }
686:
687:                 return list;
688:         }
689:
690:         private AFunctionValueImport readImportedFunction(LexIdentifierToken from)
691:                         throws ParserException, LexException
692:         {
693:                 LexNameToken name = readNameToken("Expecting imported function name", true);
694:                 LexNameToken defname = getDefName(from, name);
695:                 LexNameList typeParams = getDefinitionReader().readTypeParams();
696:
697:                 PType type = null;
698:
699:•                if (lastToken().is(VDMToken.COLON))
700:                 {
701:                         nextToken();
702:                         type = getTypeReader().readType();
703:                 }
704:
705:                 LexNameToken renamed = null;
706:
707:•                if (ignore(VDMToken.RENAMED))
708:                 {
709:                         renamed = readNameToken("Expected renamed function name", true);
710:                 }
711:
712:                 return AstFactory.newAFunctionValueImport(defname, type, typeParams, renamed);
713:         }
714:
715:         private List<PImport> readImportedOperations(LexIdentifierToken from)
716:                         throws ParserException, LexException
717:         {
718:                 List<PImport> list = new Vector<PImport>();
719:                 list.add(readImportedOperation(from));
720:                 boolean semi = ignore(VDMToken.SEMICOLON);
721:
722:•                while (lastToken().is(VDMToken.IDENTIFIER)
723:•                                || lastToken().is(VDMToken.NAME))
724:                 {
725:•                        if (!semi && Settings.strict)
726:                         {
727:                                 warning(5023, "Strict: expecting semi-colon between imports", lastToken().location);
728:                         }
729:
730:                         list.add(readImportedOperation(from));
731:                         semi = ignore(VDMToken.SEMICOLON);
732:                 }
733:
734:                 return list;
735:         }
736:
737:         private AOperationValueImport readImportedOperation(LexIdentifierToken from)
738:                         throws ParserException, LexException
739:         {
740:                 LexNameToken name = readNameToken("Expecting imported operation name", false);
741:                 LexNameToken defname = getDefName(from, name);
742:                 PType type = null;
743:
744:•                if (lastToken().is(VDMToken.COLON))
745:                 {
746:                         nextToken();
747:                         type = getTypeReader().readOperationType();
748:                 }
749:
750:                 LexNameToken renamed = null;
751:
752:•                if (ignore(VDMToken.RENAMED))
753:                 {
754:                         renamed = readNameToken("Expected renamed operation name", false);
755:                 }
756:
757:                 return AstFactory.newAOperationValueImport(defname, type, renamed);
758:         }
759:
760:         private boolean newType() throws LexException
761:         {
762:•                switch (lastToken().type)
763:                 {
764:                         case TYPES:
765:                         case VALUES:
766:                         case FUNCTIONS:
767:                         case OPERATIONS:
768:                         case EOF:
769:                                 return true;
770:                                 
771:                         default:
772:                                 return false;
773:                 }
774:         }
775:
776:         private LexNameToken getDefName(LexIdentifierToken impmod, LexNameToken name)
777:         {
778:•                if (name.module.equals(getCurrentModule())) // ie. it was an id
779:                 {
780:                         return new LexNameToken(impmod.getName(), name.name, name.location);
781:                 }
782:
783:                 return name;
784:         }
785:
786:         private LexNameList ignoreTypeParams() throws LexException, ParserException
787:         {
788:•                if (lastToken().is(VDMToken.SEQ_OPEN))
789:                 {
790:                         return getDefinitionReader().readTypeParams();
791:                 }
792:                 else
793:                 {
794:                         return null;
795:                 }
796:         }
797: }