Package: PatternReader

PatternReader

nameinstructionbranchcomplexitylinemethod
PatternReader(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%
readMaplet()
M: 0 C: 15
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
readMapletPatternList()
M: 6 C: 15
71%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 1 C: 4
80%
M: 0 C: 1
100%
readNamePatternList(String)
M: 28 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
readNamePatternPair(String)
M: 20 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
readPattern()
M: 19 C: 52
73%
M: 5 C: 7
58%
M: 4 C: 4
50%
M: 5 C: 14
74%
M: 0 C: 1
100%
readPatternList()
M: 0 C: 21
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
readSimplePattern()
M: 103 C: 316
75%
M: 13 C: 33
72%
M: 10 C: 20
67%
M: 24 C: 79
77%
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.List;
27: import java.util.Vector;
28:
29: import org.overture.ast.factory.AstFactory;
30: import org.overture.ast.lex.LexBooleanToken;
31: import org.overture.ast.lex.LexCharacterToken;
32: import org.overture.ast.lex.LexIdentifierToken;
33: import org.overture.ast.lex.LexIntegerToken;
34: import org.overture.ast.lex.LexKeywordToken;
35: import org.overture.ast.lex.LexNameToken;
36: import org.overture.ast.lex.LexQuoteToken;
37: import org.overture.ast.lex.LexRealToken;
38: import org.overture.ast.lex.LexStringToken;
39: import org.overture.ast.lex.LexToken;
40: import org.overture.ast.lex.VDMToken;
41: import org.overture.ast.patterns.AMapletPatternMaplet;
42: import org.overture.ast.patterns.ANamePatternPair;
43: import org.overture.ast.patterns.PPattern;
44: import org.overture.config.Release;
45: import org.overture.config.Settings;
46: import org.overture.parser.lex.LexException;
47: import org.overture.parser.lex.LexTokenReader;
48:
49: /**
50: * A syntax analyser to parse pattern definitions.
51: */
52:
53: public class PatternReader extends SyntaxReader
54: {
55:         public PatternReader(LexTokenReader reader)
56:         {
57:                 super(reader);
58:         }
59:
60:         public PPattern readPattern() throws ParserException, LexException
61:         {
62:                 PPattern pattern = readSimplePattern();
63:
64:•                while (lastToken().is(VDMToken.UNION)
65:•                                || lastToken().is(VDMToken.CONCATENATE)
66:•                                || lastToken().is(VDMToken.MUNION))
67:                 {
68:                         LexToken token = lastToken();
69:
70:•                        switch (token.type)
71:                         {
72:                                 case UNION:
73:                                         nextToken();
74:                                         pattern = AstFactory.newAUnionPattern(pattern, token.location, readPattern());
75:                                         break;
76:
77:                                 case CONCATENATE:
78:                                         nextToken();
79:                                         pattern = AstFactory.newAConcatenationPattern(pattern, token.location, readPattern());
80:                                         break;
81:
82:                                 case MUNION:
83:•                                        if (Settings.release == Release.VDM_10)
84:                                         {
85:                                                 nextToken();
86:                                                 pattern = AstFactory.newAMapUnionPattern(pattern, token.location, readPattern());
87:                                         } else
88:                                         {
89:                                                 throwMessage(2298, "Map patterns not available in VDM classic");
90:                                         }
91:                                         break;
92:                                 default:
93:                                         break;
94:                         }
95:                 }
96:
97:                 return pattern;
98:         }
99:
100:         private PPattern readSimplePattern() throws ParserException, LexException
101:         {
102:                 PPattern pattern = null;
103:                 LexToken token = lastToken();
104:                 boolean rdtok = true;
105:
106:•                switch (token.type)
107:                 {
108:                         case NUMBER:
109:                                 pattern = AstFactory.newAIntegerPattern((LexIntegerToken) token);
110:                                 break;
111:
112:                         case REALNUMBER:
113:                                 pattern = AstFactory.newARealPattern((LexRealToken) token);
114:                                 break;
115:
116:                         case CHARACTER:
117:                                 pattern = AstFactory.newACharacterPattern((LexCharacterToken) token);
118:                                 break;
119:
120:                         case STRING:
121:                                 pattern = AstFactory.newAStringPattern((LexStringToken) token);
122:                                 break;
123:
124:                         case QUOTE:
125:                                 pattern = AstFactory.newAQuotePattern((LexQuoteToken) token);
126:                                 break;
127:
128:                         case TRUE:
129:                         case FALSE:
130:                                 pattern = AstFactory.newABooleanPattern((LexBooleanToken) token);
131:                                 break;
132:
133:                         case NIL:
134:                                 pattern = AstFactory.newANilPattern((LexKeywordToken) token);
135:                                 break;
136:
137:                         case BRA:
138:                                 nextToken();
139:                                 ExpressionReader expr = getExpressionReader();
140:                                 pattern = AstFactory.newAExpressionPattern(expr.readExpression());
141:                                 checkFor(VDMToken.KET, 2180, "Mismatched brackets in pattern");
142:                                 rdtok = false;
143:                                 break;
144:
145:                         case SET_OPEN:
146:•                                if (nextToken().is(VDMToken.SET_CLOSE))
147:                                 {
148:                                         pattern = AstFactory.newASetPattern(token.location, new Vector<PPattern>());
149:•                                } else if (lastToken().is(VDMToken.MAPLET))
150:                                 {
151:•                                        if (Settings.release == Release.VDM_10)
152:                                         {
153:                                                 pattern = AstFactory.newAMapPattern(token.location, new Vector<AMapletPatternMaplet>());
154:                                                 nextToken();
155:                                                 checkFor(VDMToken.SET_CLOSE, 2299, "Expecting {|->} empty map pattern");
156:                                                 rdtok = false;
157:                                         } else
158:                                         {
159:                                                 throwMessage(2298, "Map patterns not available in VDM classic");
160:                                         }
161:                                 } else
162:                                 {
163:                                         reader.push();
164:                                         readPattern(); // ignored
165:
166:•                                        if (lastToken().is(VDMToken.MAPLET))
167:                                         {
168:                                                 reader.pop();
169:
170:•                                                if (Settings.release == Release.VDM_10)
171:                                                 {
172:                                                         pattern = AstFactory.newAMapPattern(token.location, readMapletPatternList());
173:                                                 } else
174:                                                 {
175:                                                         throwMessage(2298, "Map patterns not available in VDM classic");
176:                                                 }
177:                                         } else
178:                                         {
179:                                                 reader.pop();
180:                                                 pattern = AstFactory.newASetPattern(token.location, readPatternList());
181:                                         }
182:                                         checkFor(VDMToken.SET_CLOSE, 2181, "Mismatched braces in pattern");
183:                                         rdtok = false;
184:                                 }
185:                                 break;
186:
187:                         case SEQ_OPEN:
188:•                                if (nextToken().is(VDMToken.SEQ_CLOSE))
189:                                 {
190:                                         pattern = AstFactory.newASeqPattern(token.location, new Vector<PPattern>());
191:                                 } else
192:                                 {
193:                                         pattern = AstFactory.newASeqPattern(token.location, readPatternList());
194:                                         checkFor(VDMToken.SEQ_CLOSE, 2182, "Mismatched square brackets in pattern");
195:                                         rdtok = false;
196:                                 }
197:                                 break;
198:
199:                         case NAME:
200:                                 throwMessage(2056, "Cannot use module'id name in patterns");
201:                                 break;
202:
203:                         case IDENTIFIER:
204:                                 LexIdentifierToken id = lastIdToken();
205:
206:•                                if (isReserved(id.name))
207:                                 {
208:                                         throwMessage(2295, "Name contains a reserved prefix", id);
209:                                 }
210:
211:•                                if (id.name.startsWith("mk_"))
212:                                 {
213:                                         nextToken();
214:
215:•                                        if (id.name.equals("mk_"))
216:                                         {
217:                                                 checkFor(VDMToken.BRA, 2183, "Expecting '(' after mk_ tuple");
218:                                                 List<PPattern> args = readPatternList();
219:                                                 
220:•                                                if (args.size() <= 1)
221:                                                 {
222:                                                         throwMessage(2184, "Tuple pattern must have >1 argument");
223:                                                 }
224:                                                 
225:                                                 pattern = AstFactory.newATuplePattern(token.location, args);
226:                                                 checkFor(VDMToken.KET, 2184, "Expecting ')' after mk_ tuple");
227:                                         } else
228:                                         {
229:                                                 checkFor(VDMToken.BRA, 2185, "Expecting '(' after "
230:                                                                 + id + " record");
231:                                                 LexNameToken typename = null;
232:                                                 int backtick = id.name.indexOf('`');
233:
234:•                                                if (backtick >= 0)
235:                                                 {
236:                                                         // Strange case of "mk_MOD`name"
237:                                                         String mod = id.name.substring(3, backtick);
238:                                                         String name = id.name.substring(backtick + 1);
239:                                                         typename = new LexNameToken(mod, name, id.location);
240:                                                 } else
241:                                                 {
242:                                                         // Regular case of "mk_Name"
243:                                                         LexIdentifierToken type = new LexIdentifierToken(id.name.substring(3), false, id.location);
244:                                                         typename = idToName(type);
245:                                                 }
246:
247:•                                                if (lastToken().is(VDMToken.KET))
248:                                                 {
249:                                                         // An empty pattern list
250:                                                         pattern = AstFactory.newARecordPattern(typename, new Vector<PPattern>());
251:                                                         nextToken();
252:                                                 } else
253:                                                 {
254:                                                         pattern = AstFactory.newARecordPattern(typename, readPatternList());
255:                                                         checkFor(VDMToken.KET, 2186, "Expecting ')' after "
256:                                                                         + id + " record");
257:                                                 }
258:                                         }
259:
260:                                         rdtok = false;
261:                                 }
262:•                                else if (id.name.startsWith("obj_"))        // Object pattern
263:                                 {
264:•                                        if (Settings.release == Release.CLASSIC)
265:                                         {
266:                                                 throwMessage(2323, "Object patterns not available in VDM classic", Integer.MAX_VALUE);
267:                                         }
268:•                                        else if (id.name.equals("obj_"))
269:                                         {
270:                                                 throwMessage(2319, "Expecting class name after obj_ in object pattern");
271:                                         }
272:                                         else
273:                                         {
274:                                                 nextToken();
275:                                                 String classname = id.name.substring(4);
276:                                                 LexNameToken name = new LexNameToken("CLASS", classname, id.location);
277:                                                 checkFor(VDMToken.BRA, 2320, "Expecting '(' after obj_ pattern");
278:                                                 pattern = AstFactory.newAObjectPattern(name, readNamePatternList(classname));
279:                                                 checkFor(VDMToken.KET, 2322, "Expecting ')' after obj_ pattern");
280:                                                 rdtok = false;
281:                                         }
282:                                 }
283:                                 else
284:                                 {
285:                                         pattern = AstFactory.newAIdentifierPattern(idToName(id));
286:                                 }
287:                                 break;
288:
289:                         case MINUS:
290:                                 pattern = AstFactory.newAIgnorePattern(token.location);
291:                                 break;
292:
293:                         default:
294:                                 throwMessage(2057, "Unexpected token in pattern");
295:                 }
296:
297:•                if (rdtok)
298:                 {
299:                         nextToken();
300:                 }
301:                 return pattern;
302:         }
303:
304:         private List<AMapletPatternMaplet> readMapletPatternList()
305:                         throws LexException, ParserException
306:         {
307:                 List<AMapletPatternMaplet> list = new Vector<AMapletPatternMaplet>();
308:                 list.add(readMaplet());
309:
310:•                while (ignore(VDMToken.COMMA))
311:                 {
312:                         list.add(readMaplet());
313:                 }
314:
315:                 return list;
316:         }
317:
318:         private AMapletPatternMaplet readMaplet() throws ParserException,
319:                         LexException
320:         {
321:                 PPattern key = readPattern();
322:                 checkFor(VDMToken.MAPLET, 2297, "Expecting '|->' in map pattern");
323:                 PPattern value = readPattern();
324:
325:                 return AstFactory.newAMapletPatternMaplet(key, value);
326:         }
327:
328:         public List<PPattern> readPatternList() throws ParserException,
329:                         LexException
330:         {
331:                 List<PPattern> list = new Vector<PPattern>();
332:                 list.add(readPattern());
333:
334:•                while (ignore(VDMToken.COMMA))
335:                 {
336:                         list.add(readPattern());
337:                 }
338:
339:                 return list;
340:         }
341:
342:         private ANamePatternPair readNamePatternPair(String classname) throws LexException, ParserException
343:         {
344:                 LexNameToken fieldname = lastNameToken().getModifiedName(classname);
345:                 nextToken();
346:                 checkFor(VDMToken.MAPLET, 2321, "Expecting '|->' in object pattern");
347:                 PPattern pattern = readPattern();
348:
349:                 return AstFactory.newANamePatternPair(fieldname, pattern);
350:         }
351:
352:         private List<ANamePatternPair> readNamePatternList(String classname) throws LexException, ParserException
353:         {
354:                 List<ANamePatternPair> list = new Vector<ANamePatternPair>();
355:                 
356:•                if (lastToken().is(VDMToken.IDENTIFIER))        // Can be empty
357:                 {
358:                         list.add(readNamePatternPair(classname));
359:         
360:•                        while (ignore(VDMToken.COMMA))
361:                         {
362:                                 list.add(readNamePatternPair(classname));
363:                         }
364:                 }
365:
366:                 return list;
367:         }
368: }