public PType readType() throws ParserException, LexException { PType type = readUnionType(); if (lastToken().is(VDMToken.ARROW) || lastToken().is(VDMToken.TOTAL_FUNCTION)) { LexToken token = lastToken(); nextToken(); PType result = readType(); if (result instanceof AVoidType) { throwMessage(2070, "Function type cannot return void type"); } type = AstFactory.newAFunctionType( token.location, token.is(VDMToken.ARROW), productExpand(type), result); } return type; }
public List<AFieldField> readFieldList() throws ParserException, LexException { List<AFieldField> list = new Vector<AFieldField>(); while (lastToken().isNot(VDMToken.END) && lastToken().isNot(VDMToken.SEMICOLON) && lastToken().isNot(VDMToken.INV)) { reader.push(); LexToken tag = lastToken(); LexToken separator = nextToken(); if (separator.is(VDMToken.COLON)) { if (tag.isNot(VDMToken.IDENTIFIER)) { throwMessage(2071, "Expecting field identifier before ':'"); } nextToken(); LexIdentifierToken tagid = (LexIdentifierToken) tag; if (tagid.isOld()) { throwMessage(2295, "Can't use old name here", tag); } LexNameToken tagname = idToName(tagid); list.add(AstFactory.newAFieldField(tagname, tagid.getName(), readType(), false)); reader.unpush(); } else if (separator.is(VDMToken.EQABST)) { if (tag.isNot(VDMToken.IDENTIFIER)) { throwMessage(2072, "Expecting field name before ':-'"); } nextToken(); LexIdentifierToken tagid = (LexIdentifierToken) tag; if (tagid.isOld()) { throwMessage(2295, "Can't use old name here", tag); } LexNameToken tagname = idToName(tagid); list.add(AstFactory.newAFieldField(tagname, tagid.getName(), readType(), true)); reader.unpush(); } else // Anonymous field or end of fields { try { reader.retry(); String anon = Integer.toString(list.size() + 1); PType ftype = readType(); LexNameToken tagname = new LexNameToken(getCurrentModule(), anon, ftype.getLocation()); list.add(AstFactory.newAFieldField(tagname, anon, ftype, false)); reader.unpush(); } catch (Exception e) { // End? EOF? Or badly formed type, fails elsewhere... reader.pop(); break; } } } for (PField f1 : list) { for (PField f2 : list) { if (f1 != f2 && ((AFieldField) f1).getTag().equals(((AFieldField) f2).getTag())) { throwMessage(2073, "Duplicate field names in record type"); } } } return list; }