Package: StatementReader

StatementReader

nameinstructionbranchcomplexitylinemethod
StatementReader(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%
readAlwaysStatement(ILexLocation)
M: 0 C: 23
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
readAnyStatement()
M: 32 C: 139
81%
M: 8 C: 22
73%
M: 6 C: 22
79%
M: 10 C: 54
84%
M: 0 C: 1
100%
readAssignmentDefinition()
M: 5 C: 49
91%
M: 2 C: 4
67%
M: 2 C: 2
50%
M: 1 C: 11
92%
M: 0 C: 1
100%
readAssignmentOrCallStatement(LexToken)
M: 17 C: 39
70%
M: 2 C: 0
0%
M: 1 C: 1
50%
M: 4 C: 14
78%
M: 0 C: 1
100%
readAssignmentStatement(ILexLocation)
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%
readAtomicStatement(ILexLocation)
M: 0 C: 66
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 12
100%
M: 0 C: 1
100%
readBlockStatement(ILexLocation)
M: 38 C: 55
59%
M: 5 C: 7
58%
M: 4 C: 3
43%
M: 10 C: 13
57%
M: 0 C: 1
100%
readCallStatement()
M: 0 C: 10
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
readCaseAlternatives()
M: 0 C: 41
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 9
100%
M: 0 C: 1
100%
readCasesStatement(ILexLocation)
M: 0 C: 64
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 15
100%
M: 0 C: 1
100%
readConditionalStatement(ILexLocation)
M: 0 C: 55
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 14
100%
M: 0 C: 1
100%
readCyclesStatement(ILexLocation)
M: 0 C: 27
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
readDclStatements()
M: 0 C: 35
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
readDefStatement(ILexLocation)
M: 0 C: 39
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
readDurationStatement(ILexLocation)
M: 0 C: 27
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
readElseIfStatement(ILexLocation)
M: 0 C: 17
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
readExitStatement(ILexLocation)
M: 0 C: 26
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
readForIndexStatement(ILexLocation)
M: 0 C: 55
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 12
100%
M: 0 C: 1
100%
readForPatternBindStatement(ILexLocation)
M: 0 C: 56
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 12
100%
M: 0 C: 1
100%
readForStatement(ILexLocation)
M: 17 C: 85
83%
M: 2 C: 2
50%
M: 1 C: 2
67%
M: 4 C: 24
86%
M: 0 C: 1
100%
readLetBeStStatement(ILexLocation)
M: 0 C: 35
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
readLetDefStatement(ILexLocation)
M: 0 C: 36
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 7
100%
M: 0 C: 1
100%
readLetStatement(LexToken)
M: 2 C: 59
97%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 0 C: 18
100%
M: 0 C: 1
100%
readNonDetStatement(ILexLocation)
M: 0 C: 37
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
readObjectCallStatement()
M: 10 C: 52
84%
M: 1 C: 7
88%
M: 1 C: 4
80%
M: 3 C: 12
80%
M: 0 C: 1
100%
readObjectDesignator()
M: 4 C: 84
95%
M: 1 C: 11
92%
M: 1 C: 7
88%
M: 1 C: 25
96%
M: 0 C: 1
100%
readReturnStatement(ILexLocation)
M: 0 C: 38
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 12
100%
M: 0 C: 1
100%
readSimpleCallStatement()
M: 0 C: 46
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 10
100%
M: 0 C: 1
100%
readSimpleObjectDesignator()
M: 12 C: 62
84%
M: 2 C: 7
78%
M: 2 C: 5
71%
M: 3 C: 14
82%
M: 0 C: 1
100%
readSpecStatement(ILexLocation)
M: 0 C: 20
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
readStartStatement(ILexLocation)
M: 0 C: 23
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
readStartlistStatement(ILexLocation)
M: 0 C: 23
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
readStateDesignator()
M: 4 C: 55
93%
M: 0 C: 8
100%
M: 0 C: 5
100%
M: 1 C: 13
93%
M: 0 C: 1
100%
readStatement()
M: 33 C: 20
38%
M: 3 C: 1
25%
M: 2 C: 1
33%
M: 7 C: 7
50%
M: 0 C: 1
100%
readStopStatement(ILexLocation)
M: 23 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
readStoplistStatement(ILexLocation)
M: 23 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
readTixeStatement(ILexLocation)
M: 0 C: 61
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 15
100%
M: 0 C: 1
100%
readTrapStatement(ILexLocation)
M: 0 C: 33
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 7
100%
M: 0 C: 1
100%
readWhileStatement(ILexLocation)
M: 0 C: 23
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
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.util.Collections;
27: import java.util.List;
28: import java.util.Vector;
29:
30: import org.overture.ast.annotations.PAnnotation;
31: import org.overture.ast.definitions.AAssignmentDefinition;
32: import org.overture.ast.definitions.PDefinition;
33: import org.overture.ast.expressions.PExp;
34: import org.overture.ast.factory.AstFactory;
35: import org.overture.ast.intf.lex.ILexCommentList;
36: import org.overture.ast.intf.lex.ILexLocation;
37: import org.overture.ast.lex.Dialect;
38: import org.overture.ast.lex.LexIdentifierToken;
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.patterns.ADefPatternBind;
43: import org.overture.ast.patterns.PMultipleBind;
44: import org.overture.ast.patterns.PPattern;
45: import org.overture.ast.statements.AApplyObjectDesignator;
46: import org.overture.ast.statements.AAssignmentStm;
47: import org.overture.ast.statements.ABlockSimpleBlockStm;
48: import org.overture.ast.statements.ACaseAlternativeStm;
49: import org.overture.ast.statements.ACasesStm;
50: import org.overture.ast.statements.AElseIfStm;
51: import org.overture.ast.statements.AFieldObjectDesignator;
52: import org.overture.ast.statements.AIdentifierObjectDesignator;
53: import org.overture.ast.statements.ALetBeStStm;
54: import org.overture.ast.statements.ALetStm;
55: import org.overture.ast.statements.ANonDeterministicSimpleBlockStm;
56: import org.overture.ast.statements.ASpecificationStm;
57: import org.overture.ast.statements.ATixeStmtAlternative;
58: import org.overture.ast.statements.PObjectDesignator;
59: import org.overture.ast.statements.PStateDesignator;
60: import org.overture.ast.statements.PStm;
61: import org.overture.ast.typechecker.NameScope;
62: import org.overture.ast.types.PType;
63: import org.overture.config.Release;
64: import org.overture.config.Settings;
65: import org.overture.parser.lex.LexException;
66: import org.overture.parser.lex.LexTokenReader;
67:
68: /**
69: * A syntax analyser to parse statements.
70: */
71:
72: public class StatementReader extends SyntaxReader
73: {
74:         public StatementReader(LexTokenReader reader)
75:         {
76:                 super(reader);
77:         }
78:         public PStm readStatement() throws ParserException, LexException
79:         {
80:                 ILexCommentList comments = getComments();
81:                 List<PAnnotation> annotations = readAnnotations(comments);
82:                 PStm stmt = null;
83:
84:•                if (!annotations.isEmpty())
85:                 {
86:                         beforeAnnotations(this, annotations);
87:                         stmt = readAnyStatement();
88:                         afterAnnotations(this, annotations, stmt);
89:                         
90:                         Collections.reverse(annotations);        // Build the chain backwards
91:                         
92:•                        for (PAnnotation annotation: annotations)
93:                         {
94:                                 stmt = AstFactory.newAAnnotatedStm(annotation.getName().getLocation(), annotation, stmt);
95:                         }
96:                 }
97:                 else
98:                 {
99:                         stmt = readAnyStatement();
100:                 }
101:                 
102:                 stmt.setComments(comments);
103:                 return stmt;
104:         }
105:
106:         public PStm readAnyStatement() throws ParserException, LexException
107:         {
108:                 ILexCommentList comments = getComments();
109:                 PStm stmt = null;
110:                 LexToken token = lastToken();
111:                 ILexLocation location = token.location;
112:
113:•                switch (token.type)
114:                 {
115:                         case LET:
116:                                 stmt = readLetStatement(token);
117:                                 break;
118:
119:                         case RETURN:
120:                                 stmt = readReturnStatement(location);
121:                                 break;
122:
123:                         case BRA:
124:                                 stmt = readBlockStatement(location);
125:                                 break;
126:
127:                         case NAME:
128:                         case IDENTIFIER:
129:                         case NEW:
130:                         case SELF:
131:                                 stmt = readAssignmentOrCallStatement(token);
132:                                 break;
133:
134:                         case IF:
135:                                 nextToken(); // to allow elseif to call it too
136:                                 stmt = readConditionalStatement(location);
137:                                 break;
138:
139:                         case CASES:
140:                                 stmt = readCasesStatement(location);
141:                                 break;
142:
143:                         case FOR:
144:                                 stmt = readForStatement(location);
145:                                 break;
146:
147:                         case WHILE:
148:                                 stmt = readWhileStatement(location);
149:                                 break;
150:
151:                         case PIPEPIPE:
152:                                 stmt = readNonDetStatement(location);
153:                                 break;
154:
155:                         case ALWAYS:
156:                                 stmt = readAlwaysStatement(location);
157:                                 break;
158:
159:                         case ATOMIC:
160:                                 stmt = readAtomicStatement(location);
161:                                 break;
162:
163:                         case TRAP:
164:                                 stmt = readTrapStatement(location);
165:                                 break;
166:
167:                         case TIXE:
168:                                 stmt = readTixeStatement(location);
169:                                 break;
170:
171:                         case DEF:
172:                                 stmt = readDefStatement(location);
173:                                 break;
174:
175:                         case EXIT:
176:                                 stmt = readExitStatement(location);
177:                                 break;
178:
179:                         case SEQ_OPEN:
180:                                 stmt = readSpecStatement(location);
181:                                 break;
182:
183:                         case ERROR:
184:                                 stmt = AstFactory.newAErrorStm(location);
185:                                 nextToken();
186:                                 break;
187:
188:                         case SKIP:
189:                                 stmt = AstFactory.newASkipStm(location);
190:                                 nextToken();
191:                                 break;
192:
193:                         case START:
194:                                 stmt = readStartStatement(location);
195:                                 break;
196:
197:                         case STARTLIST:
198:                                 stmt = readStartlistStatement(location);
199:                                 break;
200:
201:                         case STOP:
202:•                                if (Settings.release == Release.CLASSIC)
203:                                 {
204:                                         throwMessage(2304, "'stop' not available in VDM classic");
205:                                 }
206:
207:                                 stmt = readStopStatement(location);
208:                                 break;
209:
210:                         case STOPLIST:
211:•                                if (Settings.release == Release.CLASSIC)
212:                                 {
213:                                         throwMessage(2305, "'stoplist' not available in VDM classic");
214:                                 }
215:
216:                                 stmt = readStoplistStatement(location);
217:                                 break;
218:
219:                         case CYCLES:
220:                                 stmt = readCyclesStatement(location);
221:                                 break;
222:
223:                         case DURATION:
224:                                 stmt = readDurationStatement(location);
225:                                 break;
226:
227:                         // These are special error cases that can be caused by spurious semi-colons
228:                         // after a statement, such as "if test then skip; else skip;"
229:                         case ELSE:
230:                         case ELSEIF:
231:                         case IN:
232:                                 throwMessage(2063, "Unexpected token in statement - spurious semi-colon?");
233:
234:                         default:
235:                                 throwMessage(2063, "Unexpected token in statement");
236:                 }
237:
238:                 stmt.setComments(comments);
239:                 return stmt;
240:         }
241:
242:         private PStm readExitStatement(ILexLocation token) throws ParserException,
243:                         LexException
244:         {
245:                 checkFor(VDMToken.EXIT, 2190, "Expecting 'exit'");
246:
247:                 try
248:                 {
249:                         reader.push();
250:                         PExp exp = getExpressionReader().readExpression();
251:                         reader.unpush();
252:                         return AstFactory.newAExitStm(token, exp);
253:                 } catch (ParserException e)
254:                 {
255:                         reader.pop();
256:                 }
257:
258:                 return AstFactory.newAExitStm(token);
259:         }
260:
261:         private PStm readTixeStatement(ILexLocation token) throws ParserException,
262:                         LexException
263:         {
264:                 checkFor(VDMToken.TIXE, 2191, "Expecting 'tixe'");
265:
266:                 List<ATixeStmtAlternative> traps = new Vector<ATixeStmtAlternative>();
267:                 BindReader br = getBindReader();
268:                 checkFor(VDMToken.SET_OPEN, 2192, "Expecting '{' after 'tixe'");
269:
270:•                while (lastToken().isNot(VDMToken.SET_CLOSE))
271:                 {
272:                         ADefPatternBind patternBind = br.readPatternOrBind();
273:                         checkFor(VDMToken.MAPLET, 2193, "Expecting '|->' after pattern bind");
274:                         PStm result = readStatement();
275:                         traps.add(AstFactory.newATixeStmtAlternative(patternBind, result));
276:                         ignore(VDMToken.COMMA);
277:                 }
278:
279:                 nextToken();
280:                 checkFor(VDMToken.IN, 2194, "Expecting 'in' after tixe traps");
281:                 PStm body = getStatementReader().readStatement();
282:
283:                 return AstFactory.newATixeStm(token, traps, body);
284:         }
285:
286:         private PStm readTrapStatement(ILexLocation token) throws ParserException,
287:                         LexException
288:         {
289:                 checkFor(VDMToken.TRAP, 2195, "Expecting 'trap'");
290:                 ADefPatternBind patternBind = getBindReader().readPatternOrBind();
291:                 checkFor(VDMToken.WITH, 2196, "Expecting 'with' in trap statement");
292:                 PStm with = getStatementReader().readStatement();
293:                 checkFor(VDMToken.IN, 2197, "Expecting 'in' in trap statement");
294:                 PStm body = getStatementReader().readStatement();
295:                 return AstFactory.newATrapStm(token, patternBind, with, body);
296:         }
297:
298:         private PStm readAlwaysStatement(ILexLocation token)
299:                         throws ParserException, LexException
300:         {
301:                 checkFor(VDMToken.ALWAYS, 2198, "Expecting 'always'");
302:                 PStm always = getStatementReader().readStatement();
303:                 checkFor(VDMToken.IN, 2199, "Expecting 'in' after 'always' statement");
304:                 PStm body = getStatementReader().readStatement();
305:                 return AstFactory.newAAlwaysStm(token, always, body);
306:         }
307:
308:         private PStm readNonDetStatement(ILexLocation token)
309:                         throws ParserException, LexException
310:         {
311:                 checkFor(VDMToken.PIPEPIPE, 2200, "Expecting '||'");
312:                 checkFor(VDMToken.BRA, 2201, "Expecting '(' after '||'");
313:                 ANonDeterministicSimpleBlockStm block = AstFactory.newANonDeterministicSimpleBlockStm(token);
314:                 block.getStatements().add(readStatement()); // Must be one
315:
316:•                while (ignore(VDMToken.COMMA))
317:                 {
318:                         block.getStatements().add(readStatement());
319:                 }
320:
321:                 checkFor(VDMToken.KET, 2202, "Expecting ')' at end of '||' block");
322:                 return block;
323:         }
324:
325:         private PStm readAssignmentOrCallStatement(LexToken token)
326:                         throws ParserException, LexException
327:         {
328:                 ParserException assignError = null;
329:                 PStm stmt = null;
330:
331:                 try
332:                 {
333:                         reader.push();
334:                         stmt = readAssignmentStatement(token.location);
335:                         reader.unpush();
336:                         return stmt;
337:                 } catch (ParserException e)
338:                 {
339:                         e.adjustDepth(reader.getTokensRead());
340:                         reader.pop();
341:                         assignError = e;
342:                 }
343:
344:                 try
345:                 {
346:                         reader.push();
347:                         stmt = readCallStatement();
348:                         reader.unpush();
349:                         return stmt;
350:                 } catch (ParserException e)
351:                 {
352:                         e.adjustDepth(reader.getTokensRead());
353:                         reader.pop();
354:•                        throw e.deeperThan(assignError) ? e : assignError;
355:                 }
356:         }
357:
358:         private PStm readAtomicStatement(ILexLocation token)
359:                         throws ParserException, LexException
360:         {
361:                 checkFor(VDMToken.ATOMIC, 2203, "Expecting 'atomic'");
362:                 checkFor(VDMToken.BRA, 2204, "Expecting '(' after 'atomic'");
363:                 List<AAssignmentStm> assignments = new Vector<AAssignmentStm>();
364:
365:                 assignments.add(readAssignmentStatement(lastToken().location));
366:                 checkFor(VDMToken.SEMICOLON, 2205, "Expecting ';' after atomic assignment");
367:                 assignments.add(readAssignmentStatement(lastToken().location));
368:
369:•                while (lastToken().isNot(VDMToken.KET))
370:                 {
371:                         checkFor(VDMToken.SEMICOLON, 2205, "Expecting ';' after atomic assignment");
372:                         
373:•                        if (lastToken().isNot(VDMToken.KET))
374:                         {
375:                                 assignments.add(readAssignmentStatement(lastToken().location));
376:                         }
377:                 }
378:
379:                 nextToken();
380:                 return AstFactory.newAAtomicStm(token, assignments);
381:         }
382:
383:         public PStm readCallStatement() throws ParserException, LexException
384:         {
385:•                if (dialect != Dialect.VDM_SL)
386:                 {
387:                         return readObjectCallStatement();
388:                 } else
389:                 {
390:                         return readSimpleCallStatement();
391:                 }
392:         }
393:
394:         private PStm readSimpleCallStatement() throws ParserException, LexException
395:         {
396:                 LexNameToken name = readNameToken("Expecting operation name in call statement", true);
397:
398:                 checkFor(VDMToken.BRA, 2206, "Expecting '(' after call operation name");
399:                 List<PExp> args = new Vector<PExp>();
400:                 ExpressionReader er = getExpressionReader();
401:
402:•                if (lastToken().isNot(VDMToken.KET))
403:                 {
404:                         args.add(er.readExpression());
405:
406:•                        while (ignore(VDMToken.COMMA))
407:                         {
408:                                 args.add(er.readExpression());
409:                         }
410:                 }
411:
412:                 checkFor(VDMToken.KET, 2124, "Expecting ')' after args");
413:
414:                 return AstFactory.newACallStm(name, args);
415:         }
416:
417:         private PStm readObjectCallStatement() throws ParserException, LexException
418:         {
419:                 PObjectDesignator designator = readObjectDesignator();
420:
421:                 // All operation calls actually look like object apply designators,
422:                 // since they end with <name>([args]). So we unpick the apply
423:                 // designator to extract the operation name and args.
424:
425:•                if (!(designator instanceof AApplyObjectDesignator))
426:                 {
427:                         throwMessage(2064, "Expecting <object>.identifier(args) or name(args)");
428:                 }
429:
430:                 AApplyObjectDesignator oad = (AApplyObjectDesignator) designator;
431:                 List<PExp> args = oad.getArgs();
432:
433:•                if (oad.getObject() instanceof AFieldObjectDesignator)
434:                 {
435:                         AFieldObjectDesignator ofd = (AFieldObjectDesignator) oad.getObject();
436:
437:•                        if (ofd.getClassName() != null)
438:                         {
439:                                 return AstFactory.newACallObjectStm(ofd.getObject(), ofd.getClassName(), args);
440:                         } else
441:                         {
442:                                 return AstFactory.newACallObjectStm(ofd.getObject(), (LexIdentifierToken) ofd.getFieldName().clone(), args);
443:                         }
444:•                } else if (oad.getObject() instanceof AIdentifierObjectDesignator)
445:                 {
446:                         AIdentifierObjectDesignator oid = (AIdentifierObjectDesignator) oad.getObject();
447:                         return AstFactory.newACallStm(oid.getName(), args);
448:                 } else
449:                 {
450:                         throwMessage(2065, "Expecting <object>.name(args) or name(args)");
451:                         return null;
452:                 }
453:         }
454:
455:         private PObjectDesignator readObjectDesignator() throws ParserException,
456:                         LexException
457:         {
458:                 PObjectDesignator des = readSimpleObjectDesignator();
459:                 boolean done = false;
460:
461:•                while (!done)
462:                 {
463:•                        switch (lastToken().type)
464:                         {
465:                                 case POINT:
466:                                         LexToken field = nextToken();
467:
468:                                         // If we just read a qualified name, we're dealing with
469:                                         // something like new A().X`op(), else it's the more usual
470:                                         // new A().op().
471:
472:•                                        switch (field.type)
473:                                         {
474:                                                 case IDENTIFIER:
475:                                                         des = AstFactory.newAFieldObjectDesignator(des, (LexIdentifierToken) field);
476:                                                         break;
477:
478:                                                 case NAME:
479:                                                         des = AstFactory.newAFieldObjectDesignator(des, (LexNameToken) field);
480:                                                         break;
481:
482:                                                 default:
483:                                                         throwMessage(2066, "Expecting object field name");
484:                                         }
485:
486:                                         nextToken();
487:                                         break;
488:
489:                                 case BRA:
490:                                         nextToken();
491:                                         ExpressionReader er = getExpressionReader();
492:                                         List<PExp> args = new Vector<PExp>();
493:
494:•                                        if (lastToken().isNot(VDMToken.KET))
495:                                         {
496:                                                 args.add(er.readExpression());
497:
498:•                                                while (ignore(VDMToken.COMMA))
499:                                                 {
500:                                                         args.add(er.readExpression());
501:                                                 }
502:                                         }
503:
504:                                         checkFor(VDMToken.KET, 2124, "Expecting ')' after args");
505:                                         des = AstFactory.newAApplyObjectDesignator(des, args);
506:                                         break;
507:
508:                                 default:
509:                                         done = true;
510:                                         break;
511:                         }
512:                 }
513:
514:                 return des;
515:         }
516:
517:         private PObjectDesignator readSimpleObjectDesignator() throws LexException,
518:                         ParserException
519:         {
520:                 LexToken token = readToken();
521:
522:•                switch (token.type)
523:                 {
524:                         case SELF:
525:                                 return AstFactory.newASelfObjectDesignator(token.location);
526:
527:                         case IDENTIFIER:
528:                         {
529:                                 return AstFactory.newAIdentifierObjectDesignator(idToName((LexIdentifierToken) token));
530:                         }
531:                         case NAME:
532:                         {
533:                                 return AstFactory.newAIdentifierObjectDesignator((LexNameToken) token);
534:                         }
535:                         case NEW:
536:                                 LexIdentifierToken name = readIdToken("Expecting class name after 'new'");
537:                                 checkFor(VDMToken.BRA, 2207, "Expecting '(' after new class name");
538:
539:                                 List<PExp> args = new Vector<PExp>();
540:                                 ExpressionReader er = getExpressionReader();
541:
542:•                                if (lastToken().isNot(VDMToken.KET))
543:                                 {
544:                                         args.add(er.readExpression());
545:
546:•                                        while (ignore(VDMToken.COMMA))
547:                                         {
548:                                                 args.add(er.readExpression());
549:                                         }
550:                                 }
551:
552:                                 checkFor(VDMToken.KET, 2124, "Expecting ')' after constructor args");
553:
554:                                 return AstFactory.newANewObjectDesignator(name, args);
555:
556:                         default:
557:                                 throwMessage(2067, "Expecting 'self', 'new' or name in object designator");
558:                                 break;
559:                 }
560:
561:                 return null;
562:         }
563:
564:         private PStm readWhileStatement(ILexLocation token) throws ParserException,
565:                         LexException
566:         {
567:                 checkFor(VDMToken.WHILE, 2208, "Expecting 'while'");
568:                 PExp exp = getExpressionReader().readExpression();
569:                 checkFor(VDMToken.DO, 2209, "Expecting 'do' after while expression");
570:                 PStm body = getStatementReader().readStatement();
571:                 return AstFactory.newAWhileStm(token, exp, body);
572:         }
573:
574:         private PStm readForStatement(ILexLocation token) throws ParserException,
575:                         LexException
576:         {
577:                 checkFor(VDMToken.FOR, 2210, "Expecting 'for'");
578:                 PStm forstmt = null;
579:
580:•                if (lastToken().is(VDMToken.ALL))
581:                 {
582:                         nextToken();
583:                         PPattern p = getPatternReader().readPattern();
584:                         checkFor(VDMToken.IN, 2211, "Expecting 'in set' after 'for all'");
585:                         checkFor(VDMToken.SET, 2212, "Expecting 'in set' after 'for all'");
586:                         PExp set = getExpressionReader().readExpression();
587:                         checkFor(VDMToken.DO, 2213, "Expecting 'do' after for all expression");
588:                         PStm body = getStatementReader().readStatement();
589:                         return AstFactory.newAForAllStm(token, p, set, body);
590:                 } else
591:                 {
592:                         ParserException forIndexError = null;
593:
594:                         try
595:                         {
596:                                 reader.push();
597:                                 forstmt = readForIndexStatement(token);
598:                                 reader.unpush();
599:                                 return forstmt;
600:                         } catch (ParserException e)
601:                         {
602:                                 e.adjustDepth(reader.getTokensRead());
603:                                 reader.pop();
604:                                 forIndexError = e;
605:                         }
606:
607:                         try
608:                         {
609:                                 reader.push();
610:                                 forstmt = readForPatternBindStatement(token);
611:                                 reader.unpush();
612:                                 return forstmt;
613:                         } catch (ParserException e)
614:                         {
615:                                 e.adjustDepth(reader.getTokensRead());
616:                                 reader.pop();
617:•                                throw e.deeperThan(forIndexError) ? e : forIndexError;
618:                         }
619:                 }
620:         }
621:
622:         private PStm readForPatternBindStatement(ILexLocation token)
623:                         throws ParserException, LexException
624:         {
625:                 ADefPatternBind pb = getBindReader().readPatternOrBind();
626:                 checkFor(VDMToken.IN, 2214, "Expecting 'in' after pattern bind");
627:
628:                 // The old syntax used to include a "reverse" keyword as part
629:                 // of the loop grammar, whereas the new VDM-10 syntax (LB:2791065)
630:                 // makes the reverse a unary sequence operator.
631:
632:•                if (Settings.release == Release.VDM_10)
633:                 {
634:                         PExp exp = getExpressionReader().readExpression();
635:                         checkFor(VDMToken.DO, 2215, "Expecting 'do' before loop statement");
636:                         PStm body = getStatementReader().readStatement();
637:                         return AstFactory.newAForPatternBindStm(token, pb, false, exp, body);
638:                 } else
639:                 {
640:                         boolean reverse = ignore(VDMToken.REVERSE);
641:                         PExp exp = getExpressionReader().readExpression();
642:                         checkFor(VDMToken.DO, 2215, "Expecting 'do' before loop statement");
643:                         PStm body = getStatementReader().readStatement();
644:                         return AstFactory.newAForPatternBindStm(token, pb, reverse, exp, body);
645:                 }
646:         }
647:
648:         private PStm readForIndexStatement(ILexLocation token)
649:                         throws ParserException, LexException
650:         {
651:                 LexIdentifierToken var = readIdToken("Expecting variable identifier");
652:                 checkFor(VDMToken.EQUALS, 2216, "Expecting '=' after for variable");
653:                 PExp from = getExpressionReader().readExpression();
654:                 checkFor(VDMToken.TO, 2217, "Expecting 'to' after from expression");
655:                 PExp to = getExpressionReader().readExpression();
656:                 PExp by = null;
657:
658:•                if (lastToken().is(VDMToken.BY))
659:                 {
660:                         nextToken();
661:                         by = getExpressionReader().readExpression();
662:                 }
663:
664:                 checkFor(VDMToken.DO, 2218, "Expecting 'do' before loop statement");
665:                 PStm body = getStatementReader().readStatement();
666:                 return AstFactory.newAForIndexStm(token, idToName(var), from, to, by, body);
667:         }
668:
669:         private PStm readConditionalStatement(ILexLocation token)
670:                         throws ParserException, LexException
671:         {
672:                 PExp exp = getExpressionReader().readExpression();
673:                 checkFor(VDMToken.THEN, 2219, "Missing 'then'");
674:                 PStm thenStmt = readStatement();
675:                 List<AElseIfStm> elseIfList = new Vector<AElseIfStm>();
676:
677:•                while (lastToken().is(VDMToken.ELSEIF))
678:                 {
679:                         LexToken elseif = lastToken();
680:                         nextToken();
681:                         elseIfList.add(readElseIfStatement(elseif.location));
682:                 }
683:
684:                 PStm elseStmt = null;
685:
686:•                if (lastToken().is(VDMToken.ELSE))
687:                 {
688:                         nextToken();
689:                         elseStmt = readStatement();
690:                 }
691:
692:                 return AstFactory.newAIfStm(token, exp, thenStmt, elseIfList, elseStmt);
693:         }
694:
695:         private AElseIfStm readElseIfStatement(ILexLocation token)
696:                         throws ParserException, LexException
697:         {
698:                 PExp exp = getExpressionReader().readExpression();
699:                 checkFor(VDMToken.THEN, 2220, "Missing 'then' after 'elseif' expression");
700:                 PStm thenStmt = readStatement();
701:                 return AstFactory.newAElseIfStm(token, exp, thenStmt);
702:         }
703:
704:         private AAssignmentStm readAssignmentStatement(ILexLocation token)
705:                         throws ParserException, LexException
706:         {
707:                 PStateDesignator sd = readStateDesignator();
708:                 checkFor(VDMToken.ASSIGN, 2222, "Expecting ':=' in state assignment statement");
709:                 return AstFactory.newAAssignmentStm(token, sd, getExpressionReader().readExpression());
710:         }
711:
712:         private PStateDesignator readStateDesignator() throws ParserException,
713:                         LexException
714:         {
715:                 LexNameToken name = readNameToken("Expecting name in assignment statement");
716:
717:                 PStateDesignator sd = AstFactory.newAIdentifierStateDesignator(name);
718:
719:•                while (lastToken().is(VDMToken.POINT) || lastToken().is(VDMToken.BRA))
720:                 {
721:•                        if (lastToken().is(VDMToken.POINT))
722:                         {
723:•                                if (nextToken().isNot(VDMToken.IDENTIFIER))
724:                                 {
725:                                         throwMessage(2068, "Expecting field identifier");
726:                                 }
727:
728:                                 sd = AstFactory.newAFieldStateDesignator(sd, lastIdToken());
729:                                 nextToken();
730:                         } else
731:                         {
732:                                 nextToken();
733:                                 PExp exp = getExpressionReader().readExpression();
734:                                 checkFor(VDMToken.KET, 2223, "Expecting ')' after map/seq reference");
735:                                 sd = AstFactory.newAMapSeqStateDesignator(sd, exp);
736:                         }
737:                 }
738:
739:                 return sd;
740:         }
741:
742:         public PStm readBlockStatement(ILexLocation token) throws ParserException,
743:                         LexException
744:         {
745:                 LexToken start = lastToken();
746:                 checkFor(VDMToken.BRA, 2224, "Expecting statement block");
747:                 ABlockSimpleBlockStm block = AstFactory.newABlockSimpleBlockStm(token, readDclStatements());
748:                 boolean problems = false;
749:
750:                 while (true) // Loop for continue in exceptions
751:                 {
752:                         try
753:                         {
754:•                                while (!lastToken().is(VDMToken.KET))
755:                                 {
756:
757:                                         block.getStatements().add(readStatement());
758:•                                        if (lastToken().isNot(VDMToken.KET)
759:•                                                        && lastToken().isNot(VDMToken.SEMICOLON))
760:                                         {
761:                                                 throwMessage(2225, "Expecting ';' after statement");
762:                                         }
763:                                         ignore(VDMToken.SEMICOLON);
764:                                 }
765:
766:                                 break;
767:                         } catch (ParserException e)
768:                         {
769:                                 problems = true;
770:                                 
771:•                                if (lastToken().is(VDMToken.EOF))
772:                                 {
773:                                         break;
774:                                 }
775:
776:                                 VDMToken[] after = { VDMToken.SEMICOLON };
777:                                 VDMToken[] upto = { VDMToken.KET };
778:                                 report(e, after, upto);
779:                                 continue;
780:                         }
781:                 }
782:
783:                 checkFor(VDMToken.KET, 2226, "Expecting ')' at end of statement block");
784:
785:•                if (!problems && block.getStatements().isEmpty())
786:                 {
787:                         throwMessage(2296, "Block cannot be empty", start);
788:                 }
789:                 return block;
790:         }
791:
792:         private List<AAssignmentDefinition> readDclStatements()
793:                         throws ParserException, LexException
794:         {
795:                 List<AAssignmentDefinition> defs = new Vector<AAssignmentDefinition>();
796:
797:•                while (lastToken().is(VDMToken.DCL))
798:                 {
799:                         nextToken();
800:                         defs.add(readAssignmentDefinition());
801:
802:•                        while (ignore(VDMToken.COMMA))
803:                         {
804:                                 defs.add(readAssignmentDefinition());
805:                         }
806:
807:                         checkFor(VDMToken.SEMICOLON, 2227, "Expecting ';' after declarations");
808:                 }
809:
810:                 return defs;
811:         }
812:
813:         public AAssignmentDefinition readAssignmentDefinition()
814:                         throws ParserException, LexException
815:         {
816:                 LexIdentifierToken name = readIdToken("Expecting variable identifier");
817:                 checkFor(VDMToken.COLON, 2228, "Expecting name:type in declaration");
818:                 PType type = getTypeReader().readType();
819:                 PExp exp = null;
820:
821:•                if (lastToken().is(VDMToken.ASSIGN))
822:                 {
823:                         nextToken();
824:                         exp = getExpressionReader().readExpression();
825:•                } else if (lastToken().is(VDMToken.EQUALSEQUALS)
826:•                                || lastToken().is(VDMToken.EQUALS))
827:                 {
828:                         throwMessage(2069, "Expecting <identifier>:<type> := <expression>");
829:                 } else
830:                 {
831:                         exp = AstFactory.newAUndefinedExp(name.location);
832:                 }
833:
834:                 return AstFactory.newAAssignmentDefinition(idToName(name), type, exp);
835:         }
836:
837:         private PStm readReturnStatement(ILexLocation token)
838:                         throws ParserException, LexException
839:         {
840:                 checkFor(VDMToken.RETURN, 2229, "Expecting 'return'");
841:
842:                 try
843:                 {
844:                         reader.push();
845:                         PExp exp = getExpressionReader().readExpression();
846:                         reader.unpush();
847:                         return AstFactory.newAReturnStm(token, exp);
848:                 } catch (ParserException e)
849:                 {
850:                         int count = reader.getTokensRead();
851:                         e.adjustDepth(count);
852:                         reader.pop();
853:
854:•                        if (count > 2)
855:                         {
856:                                 // We got some way, so error is probably in exp
857:                                 throw e;
858:                         } else
859:                         {
860:                                 // Probably just a simple return
861:                                 return AstFactory.newAReturnStm(token);
862:                         }
863:                 }
864:         }
865:
866:         private PStm readLetStatement(LexToken token) throws ParserException,
867:                         LexException
868:         {
869:                 checkFor(VDMToken.LET, 2230, "Expecting 'let'");
870:                 ParserException letDefError = null;
871:
872:                 try
873:                 {
874:                         reader.push();
875:                         ALetStm stmt = readLetDefStatement(token.location);
876:                         reader.unpush();
877:                         return stmt;
878:                 } catch (ParserException e)
879:                 {
880:                         e.adjustDepth(reader.getTokensRead());
881:                         reader.pop();
882:                         letDefError = e;
883:                 }
884:
885:                 try
886:                 {
887:                         reader.push();
888:                         ALetBeStStm stmt = readLetBeStStatement(token.location);
889:                         reader.unpush();
890:                         return stmt;
891:                 } catch (ParserException e)
892:                 {
893:                         e.adjustDepth(reader.getTokensRead());
894:                         reader.pop();
895:•                        throw e.deeperThan(letDefError) ? e : letDefError;
896:                 }
897:         }
898:
899:         private ALetStm readLetDefStatement(ILexLocation token)
900:                         throws ParserException, LexException
901:         {
902:                 DefinitionReader dr = getDefinitionReader();
903:                 List<PDefinition> localDefs = new Vector<PDefinition>();
904:                 localDefs.add(dr.readLocalDefinition(NameScope.LOCAL));
905:
906:•                while (ignore(VDMToken.COMMA))
907:                 {
908:                         localDefs.add(dr.readLocalDefinition(NameScope.LOCAL));
909:                 }
910:
911:                 checkFor(VDMToken.IN, 2231, "Expecting 'in' after local definitions");
912:                 return AstFactory.newALetStm(token, localDefs, readStatement(), false);
913:         }
914:
915:         private ALetBeStStm readLetBeStStatement(ILexLocation token)
916:                         throws ParserException, LexException
917:         {
918:                 PMultipleBind bind = getBindReader().readMultipleBind();
919:                 PExp stexp = null;
920:
921:•                if (lastToken().is(VDMToken.BE))
922:                 {
923:                         nextToken();
924:                         checkFor(VDMToken.ST, 2232, "Expecting 'st' after 'be' in let statement");
925:                         stexp = getExpressionReader().readExpression();
926:                 }
927:
928:                 checkFor(VDMToken.IN, 2233, "Expecting 'in' after bind in let statement");
929:                 return AstFactory.newALetBeStStm(token, bind, stexp, readStatement());
930:         }
931:
932:         private ACasesStm readCasesStatement(ILexLocation token)
933:                         throws ParserException, LexException
934:         {
935:                 checkFor(VDMToken.CASES, 2234, "Expecting 'cases'");
936:                 PExp exp = getExpressionReader().readExpression();
937:                 checkFor(VDMToken.COLON, 2235, "Expecting ':' after cases expression");
938:
939:                 List<ACaseAlternativeStm> cases = new Vector<ACaseAlternativeStm>();
940:                 PStm others = null;
941:                 cases.addAll(readCaseAlternatives());
942:
943:•                while (lastToken().is(VDMToken.COMMA))
944:                 {
945:•                        if (nextToken().is(VDMToken.OTHERS))
946:                         {
947:                                 nextToken();
948:                                 checkFor(VDMToken.ARROW, 2237, "Expecting '->' after others");
949:                                 others = readStatement();
950:                                 break;
951:                         } else
952:                         {
953:                                 cases.addAll(readCaseAlternatives());
954:                         }
955:                 }
956:
957:                 checkFor(VDMToken.END, 2238, "Expecting ', case alternative' or 'end' after cases");
958:                 return AstFactory.newACasesStm(token, exp, cases, others);
959:         }
960:
961:         private List<ACaseAlternativeStm> readCaseAlternatives()
962:                         throws ParserException, LexException
963:         {
964:                 List<ACaseAlternativeStm> alts = new Vector<ACaseAlternativeStm>();
965:                 List<PPattern> plist = getPatternReader().readPatternList();
966:                 checkFor(VDMToken.ARROW, 2236, "Expecting '->' after case pattern list");
967:                 PStm result = readStatement();
968:
969:•                for (PPattern p : plist)
970:                 {
971:                         p.getLocation().executable(true);
972:                         alts.add(AstFactory.newACaseAlternativeStm(p.clone(), result.clone()));
973:                 }
974:
975:                 return alts;
976:         }
977:
978:         private ALetStm readDefStatement(ILexLocation token)
979:                         throws ParserException, LexException
980:         {
981:                 checkFor(VDMToken.DEF, 2239, "Expecting 'def'");
982:                 DefinitionReader dr = getDefinitionReader();
983:                 List<PDefinition> equalsDefs = new Vector<PDefinition>();
984:
985:•                while (lastToken().isNot(VDMToken.IN))
986:                 {
987:                         equalsDefs.add(dr.readEqualsDefinition());
988:                         ignore(VDMToken.SEMICOLON);
989:                 }
990:
991:                 checkFor(VDMToken.IN, 2240, "Expecting 'in' after equals definitions");
992:
993:                 return AstFactory.newALetStm(token, equalsDefs, readStatement(), true);
994:         }
995:
996:         private ASpecificationStm readSpecStatement(ILexLocation token)
997:                         throws ParserException, LexException
998:         {
999:                 checkFor(VDMToken.SEQ_OPEN, 2241, "Expecting '['");
1000:                 DefinitionReader dr = getDefinitionReader();
1001:                 ASpecificationStm stmt = dr.readSpecification(token, true);
1002:                 checkFor(VDMToken.SEQ_CLOSE, 2242, "Expecting ']' after specification statement");
1003:                 return stmt;
1004:         }
1005:
1006:         private PStm readStartStatement(ILexLocation location) throws LexException,
1007:                         ParserException
1008:         {
1009:                 checkFor(VDMToken.START, 2243, "Expecting 'start'");
1010:                 checkFor(VDMToken.BRA, 2244, "Expecting 'start('");
1011:                 PExp obj = getExpressionReader().readExpression();
1012:                 checkFor(VDMToken.KET, 2245, "Expecting ')' after start object");
1013:                 return AstFactory.newAStartStm(location, obj);
1014:         }
1015:
1016:         private PStm readStartlistStatement(ILexLocation location)
1017:                         throws LexException, ParserException
1018:         {
1019:                 checkFor(VDMToken.STARTLIST, 2246, "Expecting 'startlist'");
1020:                 checkFor(VDMToken.BRA, 2247, "Expecting 'startlist('");
1021:                 PExp set = getExpressionReader().readExpression();
1022:                 checkFor(VDMToken.KET, 2248, "Expecting ')' after startlist objects");
1023:                 return AstFactory.newAStartStm(location, set);
1024:         }
1025:
1026:         private PStm readStopStatement(ILexLocation location) throws LexException,
1027:                         ParserException
1028:         {
1029:                 checkFor(VDMToken.STOP, 2306, "Expecting 'stop'");
1030:                 checkFor(VDMToken.BRA, 2307, "Expecting 'stop('");
1031:                 PExp obj = getExpressionReader().readExpression();
1032:                 checkFor(VDMToken.KET, 2308, "Expecting ')' after stop object");
1033:                 return AstFactory.newAStopStm(location, obj);
1034:         }
1035:
1036:         private PStm readStoplistStatement(ILexLocation location)
1037:                         throws LexException, ParserException
1038:         {
1039:                 checkFor(VDMToken.STOPLIST, 2309, "Expecting 'stoplist'");
1040:                 checkFor(VDMToken.BRA, 2310, "Expecting 'stoplist('");
1041:                 PExp set = getExpressionReader().readExpression();
1042:                 checkFor(VDMToken.KET, 2311, "Expecting ')' after stoplist objects");
1043:                 return AstFactory.newAStopStm(location, set);
1044:         }
1045:
1046:         private PStm readDurationStatement(ILexLocation location)
1047:                         throws LexException, ParserException
1048:         {
1049:                 checkFor(VDMToken.DURATION, 2271, "Expecting 'duration'");
1050:                 checkFor(VDMToken.BRA, 2272, "Expecting 'duration('");
1051:                 PExp duration = getExpressionReader().readExpression();
1052:                 checkFor(VDMToken.KET, 2273, "Expecting ')' after duration");
1053:                 PStm stmt = readStatement();
1054:                 return AstFactory.newADurationStm(location, duration, stmt);
1055:         }
1056:
1057:         private PStm readCyclesStatement(ILexLocation location)
1058:                         throws LexException, ParserException
1059:         {
1060:                 checkFor(VDMToken.CYCLES, 2274, "Expecting 'cycles'");
1061:                 checkFor(VDMToken.BRA, 2275, "Expecting 'cycles('");
1062:                 PExp duration = getExpressionReader().readExpression();
1063:                 checkFor(VDMToken.KET, 2276, "Expecting ')' after cycles");
1064:                 PStm stmt = readStatement();
1065:                 return AstFactory.newACyclesStm(location, duration, stmt);
1066:         }
1067: }