📄 compilevhdl.java
字号:
} else reportErrorMsg(nextToken, "No identifier in port list"); apList.next = null; lastPort = apList; while (nextToken.token == TOKEN_COMMA) { getNextToken(); APortList newPort = new APortList(); newPort.type = APORTLIST_NAME; if (nextToken.token != TOKEN_COMMA && nextToken.token != TOKEN_RIGHTBRACKET) { if (isKeySame(nextToken, KEY_OPEN)) { newPort.pointer = null; getNextToken(); } else { newPort.pointer = parseName(); if (nextToken.token == TOKEN_ARROW) { getNextToken(); newPort.pointer = parseName(); } } } else reportErrorMsg(nextToken, "No identifier in port list"); newPort.next = null; lastPort.next = newPort; lastPort = newPort; } return apList; } /** * Method to parse a generate statement. * It has the form: * generate_statement ::= label: generate_scheme GENERATE set_of_statements END GENERATE [label]; * generate_scheme ::= FOR generate_parameter_specification | IF condition * generate_parameter_specification ::= identifier IN discrete_range * @param label pointer to optional label. * @param gScheme generate scheme (FOR or IF). * @return generate statement structure. */ private Generate parseGenerate(TokenList label, int gScheme) throws ParseException { Generate gen = null; if (gScheme == GENSCHEME_FOR) { // should be past label and at keyword FOR if (!isKeySame(nextToken, KEY_FOR)) { reportErrorMsg(nextToken, "Expecting keyword FOR"); } } else { // should be past label and at keyword IF if (!isKeySame(nextToken, KEY_IF)) { reportErrorMsg(nextToken, "Expecting keyword IF"); } } GenScheme scheme = new GenScheme(); if (gScheme == GENSCHEME_FOR) { scheme.scheme = GENSCHEME_FOR; } else { scheme.scheme = GENSCHEME_IF; } scheme.identifier = null; scheme.range = null; scheme.condition = null; // for IF scheme only getNextToken(); if (gScheme == GENSCHEME_FOR) { // should be generate parameter specification if (nextToken.token != TOKEN_IDENTIFIER) { reportErrorMsg(nextToken, "Expecting an identifier"); } else { scheme.identifier = nextToken; } getNextToken(); // should be keyword IN if (!isKeySame(nextToken, KEY_IN)) { reportErrorMsg(nextToken, "Expecting keyword IN"); } getNextToken(); // should be discrete range scheme.range = parseDiscreteRange(); } else { scheme.condition = parseExpression(); } // should be keyword GENERATE if (!isKeySame(nextToken, KEY_GENERATE)) { reportErrorMsg(nextToken, "Expecting keyword GENERATE"); } getNextToken(); // set of statements Statements states = parseSetOfStatements(); // should be at keyword END if (!isKeySame(nextToken, KEY_END)) { reportErrorMsg(nextToken, "Expecting keyword END"); } getNextToken(); // should be at keyword GENERATE if (!isKeySame(nextToken, KEY_GENERATE)) { reportErrorMsg(nextToken, "Expecting keyword GENERATE"); } getNextToken(); // check if label should be present if (label != null) { /* For correct IEEE syntax, label is always true, but trailing * label is optional. */ if (nextToken.token == TOKEN_IDENTIFIER) { if (!label.pointer.equals(nextToken.pointer)) reportErrorMsg(nextToken, "Label mismatch"); getNextToken(); } } // should be at semicolon if (nextToken.token != TOKEN_SEMICOLON) { reportErrorMsg(nextToken, "Expecting a semicolon"); } getNextToken(); // create generate statement structure gen = new Generate(); gen.label = label; gen.genScheme = scheme; gen.statements = states; return gen; } /** * Method to parse the body declaration and return pointer to the parse tree. * The format is: * body_declaration_part :== {body_declaration_item} * body_delaration_item :== basic_declaration | component_declaration | resolution_mechanism_declaration | local_function_declaration * @return the parse tree, null if parsing error encountered. */ private BodyDeclare parseBodyDeclare() throws ParseException { BodyDeclare body =null; BodyDeclare endBody = null; Object pointer = null; int type = 0; while (!isKeySame(nextToken, KEY_BEGIN)) { // check for component declaration if (isKeySame(nextToken, KEY_COMPONENT)) { type = BODYDECLARE_COMPONENT; pointer = parseComponent(); } // check for resolution declaration else if (isKeySame(nextToken, KEY_RESOLVE)) { type = BODYDECLARE_RESOLUTION; pointer = null; getNextToken(); } // check for local function declaration else if (isKeySame(nextToken, KEY_FUNCTION)) { type = BODYDECLARE_LOCAL; pointer = null; getNextToken(); } // should be basic declaration else { type = BODYDECLARE_BASIC; pointer = parseBasicDeclare(); } BodyDeclare newBody = new BodyDeclare(); newBody.type = type; newBody.pointer = pointer; newBody.next = null; if (endBody == null) { body = endBody = newBody; } else { endBody.next = newBody; endBody = newBody; } } return body; } /** * Method to parse a basic declaration and return a pointer to the parse tree. * The form of a basic declaration is: * basic_declaration :== object_declaration | type_declaration | subtype_declaration | conversion_declaration | attribute_declaration | attribute_specification * @return pointer to basic_declaration parse tree, null if unrecoverable parsing error. */ private BasicDeclare parseBasicDeclare() throws ParseException { BasicDeclare basic = null; int type = NOBASICDECLARE; Object pointer = null; if (isKeySame(nextToken, KEY_TYPE)) { type = BASICDECLARE_TYPE; pointer = parseType(); } else { type = BASICDECLARE_OBJECT; pointer = parseObjectDeclare(); } if (type != NOBASICDECLARE) { basic = new BasicDeclare(); basic.type = type; basic.pointer = pointer; } else getNextToken(); // Bug fix , D.J.Yurach, June, 1988 return basic; } /** * Method to parse a type declaration. * It has the form: type_declaration ::= TYPE identifier IS type_definition ; * @return the type declaration structure. */ private Type parseType() throws ParseException { Type type = null; // should be at keyword TYPE if (!isKeySame(nextToken, KEY_TYPE)) { reportErrorMsg(nextToken, "Expecting keyword TYPE"); getNextToken(); return type; } getNextToken(); // should be at type identifier if (nextToken.token != TOKEN_IDENTIFIER) { reportErrorMsg(nextToken, "Expecting an identifier"); getNextToken(); return type; } TokenList ident = nextToken; getNextToken(); // should be keyword IS if (!isKeySame(nextToken, KEY_IS)) { reportErrorMsg(nextToken, "Expecting keyword IS"); getNextToken(); return type; } getNextToken(); // parse type definition Object pointer = null; int typeDefine = 0; if (isKeySame(nextToken, KEY_ARRAY)) { typeDefine = TYPE_COMPOSITE; pointer = parseCompositeType(); } else if (isKeySame(nextToken, KEY_RECORD)) { typeDefine = TYPE_COMPOSITE; pointer = parseCompositeType(); } else if (isKeySame(nextToken, KEY_RANGE)) { typeDefine = TYPE_SCALAR; pointer = null; } else if (nextToken.token == TOKEN_LEFTBRACKET) { typeDefine = TYPE_SCALAR; pointer = null; } else { reportErrorMsg(nextToken, "Invalid type definition"); getNextToken(); return type; } // should be at semicolon if (nextToken.token != TOKEN_SEMICOLON) { reportErrorMsg(nextToken, "Expecting a semicolon"); getNextToken(); return type; } getNextToken(); type = new Type(); type.identifier = ident; type.type = typeDefine; type.pointer = pointer; return type; } /** * Method to parse a composite type definition. * It has the form: * composite_type_definition ::= array_type_definition | record_type_definition */ private Composite parseCompositeType() throws ParseException { Composite compo = null; // should be ARRAY or RECORD keyword Object pointer = null; int type = 0; if (isKeySame(nextToken, KEY_ARRAY)) { type = COMPOSITE_ARRAY; pointer = parseArrayType(); } else if (isKeySame(nextToken, KEY_RECORD)) { type = COMPOSITE_RECORD; pointer = null; } else { reportErrorMsg(nextToken, "Invalid composite type"); getNextToken(); return compo; } compo = new Composite(); compo.type = type; compo.pointer = pointer; return compo; } /** * Method to parse an array type definition. * It has the form: * array_type_definition ::= unconstrained_array_definition | constrained_array_definition * unconstrained_array_definition ::= ARRAY (index_subtype_definition {, index_subtype_definition}) OF subtype_indication * constrained_array_definition ::= ARRAY index_constraint OF subtype_indication * index_constraint ::= (discrete_range {, discrete_range}) * NOTE: Only currently supporting constrained array definitions. * @return the array type definition. */ private Array parseArrayType() throws ParseException { Array array = null; // should be keyword ARRAY if (!isKeySame(nextToken, KEY_ARRAY)) { reportErrorMsg(nextToken, "Expecting keyword ARRAY"); getNextToken(); return array; } getNextToken(); // index_constraint // should be left bracket if (nextToken.token != TOKEN_LEFTBRACKET) { reportErrorMsg(nextToken, "Expecting a left bracket"); getNextToken(); return array; } getNextToken(); // should at least one discrete range IndexConstraint iConstraint = new IndexConstraint(); iConstraint.discrete = parseDiscreteRange(); iConstraint.next = null; IndexConstraint endconstraint = iConstraint; // continue while comma while (nextToken.token == TOKEN_COMMA) { getNextToken(); IndexConstraint newConstraint = new IndexConstraint(); newConstraint.discrete = parseDiscreteRange(); newConstraint.next = null; endconstraint.next = newConstraint; endconstraint = newConstraint; } // should be at right bracket if (nextToken.token != TOKEN_RIGHTBRACKET) { reportErrorMsg(nextToken, "Expecting a right bracket"); getNextToken(); return array; } getNextToken(); // should be at keyword OF if (!isKeySame(nextToken, KEY_OF)) { reportErrorMsg(nextToken, "Expecting keyword OF"); getNextToken(); return array; } getNextToken(); // subtype_indication SubTypeInd subType = parseSubtypeIndication(); // create array type definition array = new Array(); array.type = ARRAY_CONSTRAINED; Constrained constr = new Constrained(); array.pointer = constr; constr.constraint = iConstraint; constr.subType = subType; return array; } /** * Method to parse a discrete range. * The range has the form: discrete_range ::= subtype_indication | range * @return the discrete range structure. */ private DiscreteRange parseDiscreteRange() throws ParseException { DiscreteRange dRange = new DiscreteRange(); // currently only support range option dRange.type = DISCRETERANGE_RANGE; dRange.pointer = parseRange(); return dRange; } /** * Method to parse a range. * The range has the form: * range :== simple_expression direction simple_expression * direction ::= TO | DOWNTO * @return the range structure. */ private Range parseRange() throws ParseException { Range range = new Range(); // currently support only simple expression range option range.type = RANGE_SIMPLE_EXPR; range.pointer = parseRangeSimple(); return range; } /** * Method to parse a simple expression range. * The range has the form: simple_expression
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -