SignalType ParseTypeDeclaration() { ReadNextToken(); //skip type SignalType fType; string identifier = fCurrentToken.Value; fCurrentToken = fLexicalAnalyser.SkipOver(TokenType.Word, "is"); if (fCurrentToken.Equals(TokenType.Word, "array")) { fCurrentToken = fLexicalAnalyser.SkipOver(TokenType.Symbol, "("); Node from = ParseExpression(); //Used to have skip over "to" here but it can also be "downto" ReadNextToken(); Node to = ParseExpression(); fCurrentToken = fLexicalAnalyser.SkipOver(TokenType.Word, "of"); string subtypeIndication = fCurrentToken.Value; fType = FindDefinedType(); fCurrentToken = fLexicalAnalyser.SkipOver(TokenType.Symbol, ";"); ArrayTypeDeclaration ParsedArrayType = new ArrayTypeDeclaration(identifier, from.Eval(), to.Eval(), fType); ArrayTypeList.Add(ParsedArrayType); return(ParsedArrayType); } else if (fCurrentToken.Equals(TokenType.Word, "record")) { List <string> identifierList = new List <string> (); List <SignalType> subtypeIndicationList = new List <SignalType> (); ReadNextToken(); //skip "record" CheckForUnexpectedEndOfSource(); while (!fCurrentToken.Equals(TokenType.Word, "end")) { identifierList.Add(fCurrentToken.Value); fCurrentToken = fLexicalAnalyser.SkipOver(TokenType.Symbol, ":"); //Searches for the type of each record entry. fType = FindDefinedType(); subtypeIndicationList.Add(fType); fCurrentToken = fLexicalAnalyser.SkipOver(TokenType.Symbol, ";"); } //Skip Over: end record; fCurrentToken = fLexicalAnalyser.SkipOver(TokenType.Symbol, ";"); RecordTypeDeclaration ParsedRecordType = new RecordTypeDeclaration(identifier, identifierList, subtypeIndicationList); RecordTypeList.Add(ParsedRecordType); return(ParsedRecordType); } else { List <string> enumerationList = new List <string> (); fCurrentToken = fLexicalAnalyser.SkipOver(TokenType.Symbol, "("); while (!fCurrentToken.Equals(TokenType.Symbol, ";")) { enumerationList.Add(fCurrentToken.Value); //Can't use skip over "," since no "," after last entry ReadNextToken(); ReadNextToken(); } ReadNextToken(); EnumerationTypeDeclaration ParsedEnumerationType = new EnumerationTypeDeclaration(identifier, enumerationList); EnumerationTypeList.Add(ParsedEnumerationType); return(ParsedEnumerationType); } }
// This method is for determining the specified attribute for a type. // Currently only 3 attributes have been defined (left, right and length). // Attributes can be called on types or subtypes, therefore cases for each are specified below. int DetermineAttribute(string Attribute, string Type) { // It is first determined whether the subtype passed exists in the list of subtypes. if (SubtypeList.Exists(x => x.Identifier == Type)) { // The subtype is found and stored in chosenType. SubtypeDeclaration chosenType = SubtypeList.Find(x => x.Identifier == Type); // The correct attribute is fetched depending on the passed string. if (Attribute == "left") { return(chosenType.Left); } if (Attribute == "right") { return(chosenType.Right); } if (Attribute == "high") { return((chosenType.Right >= chosenType.Left) ? chosenType.Right : chosenType.Left); } if (Attribute == "low") { return(chosenType.Right >= chosenType.Left ? chosenType.Left : chosenType.Right); } if (Attribute == "length") { return(Math.Abs(chosenType.Left - chosenType.Right) + 1); } throw new ParserException("Attribute Provided is not recognised: " + Attribute); } else if (EnumerationTypeList.Exists(x => x.Identifier == Type)) { EnumerationTypeDeclaration chosenType = EnumerationTypeList.Find(x => x.Identifier == Type); if (Attribute == "left") { return(chosenType.Left); } if (Attribute == "right") { return(chosenType.Right); } if (Attribute == "length") { return(Math.Abs(chosenType.Left - chosenType.Right) + 1); } throw new ParserException("Attribute Provided is not recognised"); } // If the type passed is neither a subtype or a type an exception is thrown. else { throw new ParserException("Cannot determine attribute, Type/Subtype not recognized."); } }