/** * * * <h1>TypeDefinitionsParser</h1> * * <p>Parse Pascal type definitions. * * <p>Copyright (c) 2009 by Ronald Mak * * <p>For instructional purposes only. No warranties. */ public class TypeDefinitionsParser extends DeclarationsParser { /** * Constructor. * * @param parent the parent parser. */ public TypeDefinitionsParser(PascalParserTD parent) { super(parent); } // Synchronization set for a type identifier. private static final EnumSet<PascalTokenType> IDENTIFIER_SET = DeclarationsParser.VAR_START_SET.clone(); static { IDENTIFIER_SET.add(IDENTIFIER); } // Synchronization set for the = token. private static final EnumSet<PascalTokenType> EQUALS_SET = ConstantDefinitionsParser.CONSTANT_START_SET.clone(); static { EQUALS_SET.add(EQUALS); EQUALS_SET.add(SEMICOLON); } // Synchronization set for what follows a definition or declaration. private static final EnumSet<PascalTokenType> FOLLOW_SET = EnumSet.of(SEMICOLON); // Synchronization set for the start of the next definition or declaration. private static final EnumSet<PascalTokenType> NEXT_START_SET = DeclarationsParser.VAR_START_SET.clone(); static { NEXT_START_SET.add(SEMICOLON); NEXT_START_SET.add(IDENTIFIER); } /** * Parse type definitions. * * @param token the initial token. * @throws Exception if an error occurred. */ public void parse(Token token) throws Exception { token = synchronize(IDENTIFIER_SET); // Loop to parse a sequence of type definitions // separated by semicolons. while (token.getType() == IDENTIFIER) { String name = token.getText().toLowerCase(); SymTabEntry typeId = symTabStack.lookupLocal(name); // Enter the new identifier into the symbol table // but don't set how it's defined yet. if (typeId == null) { typeId = symTabStack.enterLocal(name); typeId.appendLineNumber(token.getLineNumber()); } else { errorHandler.flag(token, IDENTIFIER_REDEFINED, this); typeId = null; } token = nextToken(); // consume the identifier token // Synchronize on the = token. token = synchronize(EQUALS_SET); if (token.getType() == EQUALS) { token = nextToken(); // consume the = } else { errorHandler.flag(token, MISSING_EQUALS, this); } // Parse the type specification. TypeSpecificationParser typeSpecificationParser = new TypeSpecificationParser(this); TypeSpec type = typeSpecificationParser.parse(token); // Set identifier to be a type and set its type specificationt. if (typeId != null) { typeId.setDefinition(TYPE); } // Cross-link the type identifier and the type specification. if (type != null && typeId != null) { if (type.getIdentifier() == null) { type.setIdentifier(typeId); } typeId.setTypeSpec(type); } else { token = synchronize(FOLLOW_SET); } token = currentToken(); TokenType tokenType = token.getType(); // Look for one or more semicolons after a definition. if (tokenType == SEMICOLON) { while (token.getType() == SEMICOLON) { token = nextToken(); // consume the ; } } // If at the start of the next definition or declaration, // then missing a semicolon. else if (NEXT_START_SET.contains(tokenType)) { errorHandler.flag(token, MISSING_SEMICOLON, this); } token = synchronize(IDENTIFIER_SET); } } }
/** * * * <h1>VariableDeclarationsParser</h1> * * <p>解析变量申明 * * <p>Copyright (c) 2009 by Ronald Mak * * <p>For instructional purposes only. No warranties. */ public class VariableDeclarationsParser extends DeclarationsParser { // 标识符怎么定义的?同是变量申明,上下文不一样,定义不一样 private Definition definition; public VariableDeclarationsParser(PascalParserTD parent) { super(parent); } /** * 设置此申明的定义 * * @param definition the definition to set. */ protected void setDefinition(Definition definition) { this.definition = definition; } // 变量申明的同步集 static final EnumSet<PascalTokenType> IDENTIFIER_SET = DeclarationsParser.VAR_START_SET.clone(); static { IDENTIFIER_SET.add(IDENTIFIER); IDENTIFIER_SET.add(END); IDENTIFIER_SET.add(SEMICOLON); } // 下一个定义或申明的同步集 static final EnumSet<PascalTokenType> NEXT_START_SET = DeclarationsParser.ROUTINE_START_SET.clone(); static { NEXT_START_SET.add(IDENTIFIER); NEXT_START_SET.add(SEMICOLON); } public void parse(Token token) throws Exception { token = synchronize(IDENTIFIER_SET); // 遍历由分号分割的一系列变量申明 while (token.getType() == IDENTIFIER) { // 解析每一个子表标识申明,比如 a,b,c : int parseIdentifierSublist(token); token = currentToken(); TokenType tokenType = token.getType(); // 一个定义由分号结束 if (tokenType == SEMICOLON) { while (token.getType() == SEMICOLON) { token = nextToken(); // consume the ; } } else if (NEXT_START_SET.contains(tokenType)) { // 没有分号便开始下一个了。 errorHandler.flag(token, MISSING_SEMICOLON, this); } token = synchronize(IDENTIFIER_SET); } } // 子表标识同步集,这里a,b,c: int 中的a,b,c算作子表 static final EnumSet<PascalTokenType> IDENTIFIER_START_SET = EnumSet.of(IDENTIFIER, COMMA); // 标识符后的同步集 private static final EnumSet<PascalTokenType> IDENTIFIER_FOLLOW_SET = EnumSet.of(COLON, SEMICOLON); static { IDENTIFIER_FOLLOW_SET.addAll(DeclarationsParser.VAR_START_SET); } // 逗号的同步集 private static final EnumSet<PascalTokenType> COMMA_SET = EnumSet.of(COMMA, COLON, IDENTIFIER, SEMICOLON); /** * 解析标识符子表及类型说明 * * @param token the current token. * @return 一个申明中的子表标识符列表 * @throws Exception */ protected ArrayList<SymTabEntry> parseIdentifierSublist(Token token) throws Exception { ArrayList<SymTabEntry> sublist = new ArrayList<SymTabEntry>(); do { token = synchronize(IDENTIFIER_START_SET); SymTabEntry id = parseIdentifier(token); if (id != null) { sublist.add(id); } token = synchronize(COMMA_SET); TokenType tokenType = token.getType(); // 找逗号 if (tokenType == COMMA) { token = nextToken(); // 有逗号吞掉以便下一个 if (IDENTIFIER_FOLLOW_SET.contains(token.getType())) { errorHandler.flag(token, MISSING_IDENTIFIER, this); } } else if (IDENTIFIER_START_SET.contains(tokenType)) { errorHandler.flag(token, MISSING_COMMA, this); } } while (!IDENTIFIER_FOLLOW_SET.contains(token.getType())); // 冒号后面的类型 TypeSpec type = parseTypeSpec(token); // 将子表中的每个变量的类型设置上,比如a,b,c:int,先解析了a,b,c,然后解析了int类型 // 那么这儿就会给a,b,c设置上int类型 for (SymTabEntry variableId : sublist) { variableId.setTypeSpec(type); } return sublist; } /** * 解析标识符 * * @param token * @return 对应符号表项 * @throws Exception */ private SymTabEntry parseIdentifier(Token token) throws Exception { SymTabEntry id = null; if (token.getType() == IDENTIFIER) { String name = token.getText().toLowerCase(); id = symTabStack.lookupLocal(name); // 申明必须得没有,否则重定义了 if (id == null) { id = symTabStack.enterLocal(name); id.setDefinition(definition); id.appendLineNumber(token.getLineNumber()); } else { errorHandler.flag(token, IDENTIFIER_REDEFINED, this); } token = nextToken(); } else { errorHandler.flag(token, MISSING_IDENTIFIER, this); } return id; } // 类型冒号处的同步集 private static final EnumSet<PascalTokenType> COLON_SET = EnumSet.of(COLON, SEMICOLON); /** * 解析变量申明里的类型 * * @param token 当前token * @return 类型说明 * @throws Exception */ protected TypeSpec parseTypeSpec(Token token) throws Exception { // 同步在:处 token = synchronize(COLON_SET); if (token.getType() == COLON) { token = nextToken(); // 吞掉 : } else { errorHandler.flag(token, MISSING_COLON, this); } // 解析类型说明 TypeSpecificationParser typeSpecificationParser = new TypeSpecificationParser(this); TypeSpec type = typeSpecificationParser.parse(token); return type; } }