void Parser::checkDeclaration(const std::string& varName, DeclarationCheck check, SymbolType type, std::string notes) throw(ParserException) { if (!d_checksEnabled) { return; } switch (check) { case CHECK_DECLARED: if (!isDeclared(varName, type)) { parseError("Symbol '" + varName + "' not declared as a " + (type == SYM_VARIABLE ? "variable" : "type") + (notes.size() == 0 ? notes : "\n" + notes)); } break; case CHECK_UNDECLARED: if (isDeclared(varName, type)) { parseError("Symbol '" + varName + "' previously declared as a " + (type == SYM_VARIABLE ? "variable" : "type") + (notes.size() == 0 ? notes : "\n" + notes)); } break; case CHECK_NONE: break; default: assert(false); // Unhandled(check); } }
void Tptp::makeApplication(Expr& expr, std::string& name, std::vector<Expr>& args, bool term) { if (args.empty()) { // Its a constant if (isDeclared(name)) { // already appeared expr = getVariable(name); } else { Type t = term ? d_unsorted : getExprManager()->booleanType(); expr = mkVar(name, t, ExprManager::VAR_FLAG_GLOBAL); // levelZero preemptCommand(new DeclareFunctionCommand(name, expr, t)); } } else { // Its an application if (isDeclared(name)) { // already appeared expr = getVariable(name); } else { std::vector<Type> sorts(args.size(), d_unsorted); Type t = term ? d_unsorted : getExprManager()->booleanType(); t = getExprManager()->mkFunctionType(sorts, t); expr = mkVar(name, t, ExprManager::VAR_FLAG_GLOBAL); // levelZero preemptCommand(new DeclareFunctionCommand(name, expr, t)); } // args might be rationals, in which case we need to create // distinct constants of the "unsorted" sort to represent them for (size_t i = 0; i < args.size(); ++i) { if (args[i].getType().isReal() && FunctionType(expr.getType()).getArgTypes()[i] == d_unsorted) { args[i] = convertRatToUnsorted(args[i]); } } expr = getExprManager()->mkExpr(kind::APPLY_UF, expr, args); } }
void PvpInternal::makeNeutral(TangibleObject &dest) { // don't need to do anything if // the character is already neutral if ((dest.getPvpFaction() == 0) && (dest.getPvpType() == PvpType_Neutral)) return; if (!dest.isAuthoritative()) { forwardPvpMessage(dest, PvpMessages::setType.getCrc(), NetworkId::cms_invalid, 0, 0); return; } PvpUpdateObserver o(&dest, Archive::ADOO_generic); bool wasDeclared = isDeclared(dest); if (dest.getPvpType() != PvpType_Neutral) dest.setPvpType(PvpType_Neutral); if (wasDeclared) setPermFactionEnemyFlags(dest); // lose faction when made neutral if (dest.getPvpFaction() != 0) setAlignedFaction(dest, 0); }
void PvpInternal::makeOnLeave(TangibleObject &dest) { // don't need to do anything if the character // is not factional or already "on leave"; // "on leave" means character belongs to // a faction and is PvpType_Neutral if (dest.getPvpFaction() == 0) return; if (dest.getPvpType() == PvpType_Neutral) return; if (!dest.isAuthoritative()) { // 782497134 (just an arbitrary random value) is a special value to indicate "on leave" forwardPvpMessage(dest, PvpMessages::setType.getCrc(), NetworkId::cms_invalid, 0, 782497134); return; } PvpUpdateObserver o(&dest, Archive::ADOO_generic); bool wasDeclared = isDeclared(dest); dest.setPvpType(PvpType_Neutral); if (wasDeclared) setPermFactionEnemyFlags(dest); }
Type Parser::getSort(const std::string& name, const std::vector<Type>& params) { checkDeclaration(name, CHECK_DECLARED, SYM_SORT); assert( isDeclared(name, SYM_SORT) ); Type t = d_symtab->lookupType(name, params); return t; }
Type Parser::getType(const std::string& var_name, SymbolType type) { checkDeclaration(var_name, CHECK_DECLARED, type); assert( isDeclared(var_name, type) ); Type t = getSymbol(var_name, type).getType(); return t; }
void Parser::defineType(const std::string& name, const std::vector<Type>& params, const Type& type) { d_symtab->bindType(name, params, type); assert( isDeclared(name, SYM_SORT) ); }
/* Returns true if name is bound to a function-like thing (function, * constructor, tester, or selector). */ bool Parser::isFunctionLike(const std::string& name) { if (!isDeclared(name, SYM_VARIABLE)) { return false; } Type type = getType(name); return type.isFunction() || type.isConstructor() || type.isTester() || type.isSelector(); }
int outputCheck1(ASTnode* leaf){//listVar if(!isDeclared(leaf)){ semanticError(1,leaf->t); return 0; } typeCounter++; type[typeCounter]=findType(leaf,1); SymbolTableEntryNode* t=getSymbolTableNode(leaf); t->type.id.initialized=1; }
uint32_t PromelaDataModel::getLength(const std::string& expr) { if (!isDeclared(expr)) { ERROR_EXECUTION_THROW("Variable '" + expr + "' was not declared"); } if (!_variables[expr].hasKey("size")) { ERROR_EXECUTION_THROW("Variable '" + expr + "' is no array"); } return strTo<int>(_variables[expr]["size"].atom); }
Expr Parser::getSymbol(const std::string& name, SymbolType type) { checkDeclaration(name, CHECK_DECLARED, type); assert(isDeclared(name, type)); if (type == SYM_VARIABLE) { // Functions share var namespace return d_symtab->lookup(name); } assert(false); // Unhandled(type); return Expr(); }
int outputCheck(ASTnode* l){//receives leaf do{ if(!isDeclared(l->array[0])){ semanticError(1,l->array[0]->t); return 0; } typeCounter++; type[typeCounter]=findType(l->array[0],1); SymbolTableEntryNode* t=getSymbolTableNode(l->array[0]); t->type.id.initialized=1; l=l->array[1]; }while(l->array[1]!=NULL); }
void PvpInternal::makeDeclared(TangibleObject &dest) { if (!isDeclared(dest)) { if (!dest.isAuthoritative()) { forwardPvpMessage(dest, PvpMessages::setType.getCrc(), NetworkId::cms_invalid, 0, 2); return; } PvpUpdateObserver o(&dest, Archive::ADOO_generic); dest.setPvpType(PvpType_Declared); setPermFactionEnemyFlags(dest); } }
void PvpInternal::setAlignedFaction(TangibleObject &dest, Pvp::FactionId align) { if (getAlignedFaction(dest) != align) { if (!dest.isAuthoritative()) { forwardPvpMessage(dest, PvpMessages::setAlignedFaction.getCrc(), NetworkId::cms_invalid, align, 0); return; } PvpUpdateObserver o(&dest, Archive::ADOO_generic); dest.setPvpFaction(align); if (isDeclared(dest)) setPermFactionEnemyFlags(dest); } }
std::vector<DatatypeType> Parser::mkMutualDatatypeTypes( std::vector<Datatype>& datatypes) { try { std::vector<DatatypeType> types = d_exprManager->mkMutualDatatypeTypes(datatypes, d_unresolved); assert(datatypes.size() == types.size()); for (unsigned i = 0; i < datatypes.size(); ++i) { DatatypeType t = types[i]; const Datatype& dt = t.getDatatype(); const std::string& name = dt.getName(); Debug("parser-idt") << "define " << name << " as " << t << std::endl; if (isDeclared(name, SYM_SORT)) { throw ParserException(name + " already declared"); } if (t.isParametric()) { std::vector<Type> paramTypes = t.getParamTypes(); defineType(name, paramTypes, t); } else { defineType(name, t); } for (Datatype::const_iterator j = dt.begin(), j_end = dt.end(); j != j_end; ++j) { const DatatypeConstructor& ctor = *j; expr::ExprPrintTypes::Scope pts(Debug("parser-idt"), true); Expr constructor = ctor.getConstructor(); Debug("parser-idt") << "+ define " << constructor << std::endl; string constructorName = ctor.getName(); if (isDeclared(constructorName, SYM_VARIABLE)) { throw ParserException(constructorName + " already declared"); } defineVar(constructorName, constructor); Expr tester = ctor.getTester(); Debug("parser-idt") << "+ define " << tester << std::endl; string testerName = ctor.getTesterName(); if (isDeclared(testerName, SYM_VARIABLE)) { throw ParserException(testerName + " already declared"); } defineVar(testerName, tester); for (DatatypeConstructor::const_iterator k = ctor.begin(), k_end = ctor.end(); k != k_end; ++k) { Expr selector = (*k).getSelector(); Debug("parser-idt") << "+++ define " << selector << std::endl; string selectorName = (*k).getName(); if (isDeclared(selectorName, SYM_VARIABLE)) { throw ParserException(selectorName + " already declared"); } defineVar(selectorName, selector); } } } // These are no longer used, and the ExprManager would have // complained of a bad substitution if anything is left unresolved. // Clear out the set. d_unresolved.clear(); // throw exception if any datatype is not well-founded for (unsigned i = 0; i < datatypes.size(); ++i) { const Datatype& dt = types[i].getDatatype(); if (!dt.isCodatatype() && !dt.isWellFounded()) { throw ParserException(dt.getName() + " is not well-founded"); } } return types; } catch (IllegalArgumentException& ie) { throw ParserException(ie.getMessage()); } }
bool Parser::isUnresolvedType(const std::string& name) { if (!isDeclared(name, SYM_SORT)) { return false; } return d_unresolved.find(getSort(name)) != d_unresolved.end(); }
void Parser::defineFunction(const std::string& name, const Expr& val, bool levelZero) { d_symtab->bindDefinedFunction(name, val, levelZero); assert(isDeclared(name)); }
void Parser::defineVar(const std::string& name, const Expr& val, bool levelZero) { Debug("parser") << "defineVar( " << name << " := " << val << ")" << std::endl; d_symtab->bind(name, val, levelZero); assert(isDeclared(name)); }
/* Returns true if name is bound to a function returning boolean. */ bool Parser::isPredicate(const std::string& name) { return isDeclared(name, SYM_VARIABLE) && getType(name).isPredicate(); }
size_t Parser::getArity(const std::string& sort_name) { checkDeclaration(sort_name, CHECK_DECLARED, SYM_SORT); assert(isDeclared(sort_name, SYM_SORT)); return d_symtab->lookupArity(sort_name); }
void XPathDataModel::setForeach(const std::string& item, const std::string& array, const std::string& index, uint32_t iteration) { XPathValue<std::string> arrayResult = _xpath.evaluate_expr(array, _doc); assert(arrayResult.type() == NODE_SET); #if 0 std::cout << "Array Size: " << arrayResult.asNodeSet().size() << std::endl; for (size_t i = 0; i < arrayResult.asNodeSet().size(); i++) { std::cout << arrayResult.asNodeSet()[i] << std::endl; } #endif assert(arrayResult.asNodeSet().size() >= iteration); NodeSet<std::string> arrayNodeSet; arrayNodeSet.push_back(arrayResult.asNodeSet()[iteration]); if (!isDeclared(item)) { if (!isValidIdentifier(item)) ERROR_EXECUTION_THROW("Expression '" + item + "' not a valid identifier."); Element<std::string> container = _doc.createElement("data"); container.setAttribute("id", item); container.appendChild(arrayResult.asNodeSet()[iteration].cloneNode(true)); _datamodel.appendChild(container); _varResolver.setVariable(item, arrayNodeSet); } XPathValue<std::string> itemResult = _varResolver.resolveVariable("", item); assign(itemResult, arrayNodeSet, Element<std::string>()); if (index.length() > 0) { NodeSet<std::string> indexNodeSet; Text<std::string> indexElem = _doc.createTextNode(toStr(iteration)); indexNodeSet.push_back(indexElem); if (!isDeclared(index)) { Element<std::string> container = _doc.createElement("data"); container.setAttribute("id", index); container.appendChild(indexElem); _datamodel.appendChild(container); NodeSet<std::string> indexVarNodeSet; indexVarNodeSet.push_back(container); _varResolver.setVariable(index, indexVarNodeSet); } XPathValue<std::string> indexResult = _varResolver.resolveVariable("", index); assign(indexResult, indexNodeSet, Element<std::string>()); } #if 0 std::cout << _datamodel << std::endl << std::endl; std::cout << "Index: " << indexResult.asNodeSet().size() << std::endl; for (size_t i = 0; i < indexResult.asNodeSet().size(); i++) { std::cout << indexResult.asNodeSet()[i] << std::endl; } std::cout << std::endl; #endif }
CalcChecker::CalcChecker() : ANTLR_USE_NAMESPACE(antlr)TreeParser() { } void CalcChecker::program(ANTLR_USE_NAMESPACE(antlr)RefAST _t) { ANTLR_USE_NAMESPACE(antlr)RefAST program_AST_in = (_t == ANTLR_USE_NAMESPACE(antlr)RefAST(ASTNULL)) ? ANTLR_USE_NAMESPACE(antlr)nullAST : _t; try { // for error handling ANTLR_USE_NAMESPACE(antlr)RefAST __t71 = _t; ANTLR_USE_NAMESPACE(antlr)RefAST tmp1_AST_in = _t; match(_t,PROGRAM_AST); _t = _t->getFirstChild(); { // ( ... )+ int _cnt73=0; for (;;) { if (_t == ANTLR_USE_NAMESPACE(antlr)nullAST ) _t = ASTNULL; switch ( _t->getType()) { case DECL: { declaration(_t); _t = _retTree; break; } case PRINT: case BECOMES: { statement(_t); _t = _retTree; break; } default: { if ( _cnt73>=1 ) { goto _loop73; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(_t);} } } _cnt73++; } _loop73:; } // ( ... )+ _t = __t71; _t = _t->getNextSibling(); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); if ( _t != ANTLR_USE_NAMESPACE(antlr)nullAST ) _t = _t->getNextSibling(); } _retTree = _t; } void CalcChecker::declaration(ANTLR_USE_NAMESPACE(antlr)RefAST _t) { ANTLR_USE_NAMESPACE(antlr)RefAST declaration_AST_in = (_t == ANTLR_USE_NAMESPACE(antlr)RefAST(ASTNULL)) ? ANTLR_USE_NAMESPACE(antlr)nullAST : _t; ANTLR_USE_NAMESPACE(antlr)RefAST id = ANTLR_USE_NAMESPACE(antlr)nullAST; try { // for error handling ANTLR_USE_NAMESPACE(antlr)RefAST __t75 = _t; ANTLR_USE_NAMESPACE(antlr)RefAST tmp2_AST_in = _t; match(_t,DECL); _t = _t->getFirstChild(); type(_t); _t = _retTree; id = _t; match(_t,IDENTIFIER); _t = _t->getNextSibling(); _t = __t75; _t = _t->getNextSibling(); #line 231 "Calc.g" if (isDeclared(id->getText())){ cerr << id->getText() << " is already declared" << endl; exit(-1); } else declare(id->getText()); #line 88 "CalcChecker.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); if ( _t != ANTLR_USE_NAMESPACE(antlr)nullAST ) _t = _t->getNextSibling(); } _retTree = _t; } void CalcChecker::statement(ANTLR_USE_NAMESPACE(antlr)RefAST _t) { ANTLR_USE_NAMESPACE(antlr)RefAST statement_AST_in = (_t == ANTLR_USE_NAMESPACE(antlr)RefAST(ASTNULL)) ? ANTLR_USE_NAMESPACE(antlr)nullAST : _t; ANTLR_USE_NAMESPACE(antlr)RefAST id = ANTLR_USE_NAMESPACE(antlr)nullAST; try { // for error handling if (_t == ANTLR_USE_NAMESPACE(antlr)nullAST ) _t = ASTNULL; switch ( _t->getType()) { case BECOMES: { ANTLR_USE_NAMESPACE(antlr)RefAST __t77 = _t; ANTLR_USE_NAMESPACE(antlr)RefAST tmp3_AST_in = _t; match(_t,BECOMES); _t = _t->getFirstChild(); id = _t; match(_t,IDENTIFIER); _t = _t->getNextSibling(); expr(_t); _t = _retTree; _t = __t77; _t = _t->getNextSibling(); #line 243 "Calc.g" if (!isDeclared(id->getText())) { cerr << id->getText() << " is not declared" << endl; exit(-1); } //TODO: type checking #line 130 "CalcChecker.cpp" break; } case PRINT: { ANTLR_USE_NAMESPACE(antlr)RefAST __t78 = _t; ANTLR_USE_NAMESPACE(antlr)RefAST tmp4_AST_in = _t; match(_t,PRINT); _t = _t->getFirstChild(); expr(_t); _t = _retTree; _t = __t78; _t = _t->getNextSibling(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(_t); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); if ( _t != ANTLR_USE_NAMESPACE(antlr)nullAST ) _t = _t->getNextSibling(); } _retTree = _t; } void CalcChecker::type(ANTLR_USE_NAMESPACE(antlr)RefAST _t) { ANTLR_USE_NAMESPACE(antlr)RefAST type_AST_in = (_t == ANTLR_USE_NAMESPACE(antlr)RefAST(ASTNULL)) ? ANTLR_USE_NAMESPACE(antlr)nullAST : _t; try { // for error handling if (_t == ANTLR_USE_NAMESPACE(antlr)nullAST ) _t = ASTNULL; switch ( _t->getType()) { case INT: { ANTLR_USE_NAMESPACE(antlr)RefAST tmp5_AST_in = _t; match(_t,INT); _t = _t->getNextSibling(); break; } case FLOAT: { ANTLR_USE_NAMESPACE(antlr)RefAST tmp6_AST_in = _t; match(_t,FLOAT); _t = _t->getNextSibling(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(_t); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); if ( _t != ANTLR_USE_NAMESPACE(antlr)nullAST ) _t = _t->getNextSibling(); } _retTree = _t; } void CalcChecker::expr(ANTLR_USE_NAMESPACE(antlr)RefAST _t) { ANTLR_USE_NAMESPACE(antlr)RefAST expr_AST_in = (_t == ANTLR_USE_NAMESPACE(antlr)RefAST(ASTNULL)) ? ANTLR_USE_NAMESPACE(antlr)nullAST : _t; try { // for error handling if (_t == ANTLR_USE_NAMESPACE(antlr)nullAST ) _t = ASTNULL; switch ( _t->getType()) { case INT: case FLOAT: case IDENTIFIER: { operand(_t); _t = _retTree; break; } case PLUS: { ANTLR_USE_NAMESPACE(antlr)RefAST __t80 = _t; ANTLR_USE_NAMESPACE(antlr)RefAST tmp7_AST_in = _t; match(_t,PLUS); _t = _t->getFirstChild(); expr(_t); _t = _retTree; expr(_t); _t = _retTree; _t = __t80; _t = _t->getNextSibling(); #line 258 "Calc.g" /*TODO: type checking*/ #line 223 "CalcChecker.cpp" break; } case MINUS: { ANTLR_USE_NAMESPACE(antlr)RefAST __t81 = _t; ANTLR_USE_NAMESPACE(antlr)RefAST tmp8_AST_in = _t; match(_t,MINUS); _t = _t->getFirstChild(); expr(_t); _t = _retTree; expr(_t); _t = _retTree; _t = __t81; _t = _t->getNextSibling(); #line 259 "Calc.g" /*TODO: type checking*/ #line 240 "CalcChecker.cpp" break; } case MUL: { ANTLR_USE_NAMESPACE(antlr)RefAST __t82 = _t; ANTLR_USE_NAMESPACE(antlr)RefAST tmp9_AST_in = _t; match(_t,MUL); _t = _t->getFirstChild(); expr(_t); _t = _retTree; expr(_t); _t = _retTree; _t = __t82; _t = _t->getNextSibling(); #line 260 "Calc.g" /*TODO: type checking*/ #line 257 "CalcChecker.cpp" break; } case DIV: { ANTLR_USE_NAMESPACE(antlr)RefAST __t83 = _t; ANTLR_USE_NAMESPACE(antlr)RefAST tmp10_AST_in = _t; match(_t,DIV); _t = _t->getFirstChild(); expr(_t); _t = _retTree; expr(_t); _t = _retTree; _t = __t83; _t = _t->getNextSibling(); #line 261 "Calc.g" /*TODO: type checking*/ #line 274 "CalcChecker.cpp" break; } case POW: { ANTLR_USE_NAMESPACE(antlr)RefAST __t84 = _t; ANTLR_USE_NAMESPACE(antlr)RefAST tmp11_AST_in = _t; match(_t,POW); _t = _t->getFirstChild(); expr(_t); _t = _retTree; expr(_t); _t = _retTree; _t = __t84; _t = _t->getNextSibling(); #line 262 "Calc.g" /*TODO: type checking*/ #line 291 "CalcChecker.cpp" break; } case SIGN_MINUS: { ANTLR_USE_NAMESPACE(antlr)RefAST __t85 = _t; ANTLR_USE_NAMESPACE(antlr)RefAST tmp12_AST_in = _t; match(_t,SIGN_MINUS); _t = _t->getFirstChild(); expr(_t); _t = _retTree; _t = __t85; _t = _t->getNextSibling(); #line 263 "Calc.g" /*TODO: type checking*/ #line 306 "CalcChecker.cpp" break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(_t); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); if ( _t != ANTLR_USE_NAMESPACE(antlr)nullAST ) _t = _t->getNextSibling(); } _retTree = _t; } void CalcChecker::operand(ANTLR_USE_NAMESPACE(antlr)RefAST _t) { ANTLR_USE_NAMESPACE(antlr)RefAST operand_AST_in = (_t == ANTLR_USE_NAMESPACE(antlr)RefAST(ASTNULL)) ? ANTLR_USE_NAMESPACE(antlr)nullAST : _t; ANTLR_USE_NAMESPACE(antlr)RefAST id = ANTLR_USE_NAMESPACE(antlr)nullAST; try { // for error handling if (_t == ANTLR_USE_NAMESPACE(antlr)nullAST ) _t = ASTNULL; switch ( _t->getType()) { case IDENTIFIER: { id = _t; match(_t,IDENTIFIER); _t = _t->getNextSibling(); #line 268 "Calc.g" if (!isDeclared(id->getText())){ cerr << id->getText() << " is not declared" << endl; exit(-1); } #line 342 "CalcChecker.cpp" break; } case INT: { ANTLR_USE_NAMESPACE(antlr)RefAST tmp13_AST_in = _t; match(_t,INT); _t = _t->getNextSibling(); break; } case FLOAT: { ANTLR_USE_NAMESPACE(antlr)RefAST tmp14_AST_in = _t; match(_t,FLOAT); _t = _t->getNextSibling(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(_t); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); if ( _t != ANTLR_USE_NAMESPACE(antlr)nullAST ) _t = _t->getNextSibling(); } _retTree = _t; } void CalcChecker::initializeASTFactory( ANTLR_USE_NAMESPACE(antlr)ASTFactory& ) { } const char* CalcChecker::tokenNames[] = { "<0>", "EOF", "<2>", "NULL_TREE_LOOKAHEAD", "\"print\"", "\"int\"", "\"float\"", "BECOMES", "PLUS", "MINUS", "MUL", "DIV", "MOD", "POW", "COLON", "SEMICOLON", "LPAREN", "RPAREN", "LBRACKET", "RBRACKET", "COMMA", "LOWER", "UPPER", "DIGIT", "IDENTIFIER", "NUMBER", "COMMENT", "WS", "PROGRAM_AST", "DECL", "SIGN_MINUS", "SIGN_PLUS", 0 };
int findTypeBE(ASTnode* BE){ ASTnode *lhs,*rhs; int z; switch(BE->label){ case 75:// AND case 76:// OR lhs=BE->array[0]; rhs=BE->array[1]; if(findTypeBE(lhs)!=findTypeBE(rhs)){ return -1; } return findTypeBE(lhs); break; case 77:// LT case 78:// LE case 79:// EQ case 80:// GT case 81:// GE case 82:// NE lhs=BE->array[0]; rhs=BE->array[1]; if(lhs->label!=54&&rhs->label!=54){//none of them is id if(lhs->label==rhs->label) return lhs->label; else return -1; } if(lhs->label==54){ if(!isDeclared(lhs)){ semanticError(1,lhs->t); return -1; } if(rhs->label==54){ if(!isDeclared(rhs)){ semanticError(1,lhs->t); return -1; } if((z=findType(lhs,0))==findType(rhs,0)) return z; else return -1; } else{ if(findType(lhs,0)==rhs->label) return rhs->label; else return -1; } } if(rhs->label==54){ if(!isDeclared(rhs)){ semanticError(1,lhs->t); return -1; } if(findType(rhs,0)==lhs->label) return lhs->label; else return -1; } break; case 83:// NOT findType(BE->array[0],0); break; } }
void semantics(ASTnode* ASTroot){ firstMatrix=1; if(ASTroot==NULL){ return; } int z,noTraverse=0; ASTnode *rows,*l; token bufToken; SymbolTable *tmp; SymbolTableEntryNode *t; int p=0; if(sflag==0){ //first time, main function so create a symbol table for main function sflag=1; S[0]=createSymbolTable(size, NULL, "MAIN");//parentTable of Main is NULL symbolStack=createSymbolStack(); pushSymbolStack(S[0],symbolStack); p=1; counter++; } switch(ASTroot->label){ //Symbol Table creates only in 1, 61, 64 //Symbol table populates in 1:functionDef,31:declarationStmt case 1://make a new symbol table, this would be the scope unless an END is encountered, functionDef InsertSymbolTable(topSymbolStack(symbolStack), ASTroot); S[counter]=createSymbolTable(size, topSymbolStack(symbolStack),ASTroot->array[1]->t.lexeme); pushSymbolStack(S[counter],symbolStack); InsertSymbolTableFun(topSymbolStack(symbolStack), ASTroot);//for input and output arguments of function p=1; counter++; break; case 2://ifstmt S[counter]=createSymbolTable(size, topSymbolStack(symbolStack),"IF"); pushSymbolStack(S[counter],symbolStack); p=1; counter++; break; case 3: noTraverse=1; if(strcmp(topSymbolStack(symbolStack)->symbolTableName,ASTroot->array[0]->t.lexeme)==0){//checking for Recursion semanticError(3,ASTroot->array[0]->t); return; } //check for input parameter list and function signature- input and output tmp=topSymbolStack(symbolStack); while(tmp!=NULL){ z=SearchHashTable(tmp, ASTroot->array[0]->t.lexeme); if(z!=-1) break; else tmp=tmp->parentTable; } if(tmp==NULL){ semanticError(1,ASTroot->t); break; }//declaration of FunId is checked here itself t=findSymbolTableNode(tmp->table[z].next,ASTroot->array[0]->t.lexeme); if(t->type.fid.outputSize!=typeCounter){ semanticError(5,ASTroot->array[0]->t); break; } else{ for(z=0; z<=t->type.fid.outputSize; z++){ if(t->type.fid.output[z]!=type[z]){ semanticError(5,ASTroot->array[0]->t); noTraverse=1; break;//from for } } typeCounter=-1;//successfully implemented. } l=ASTroot->array[1]; for(z=0; z<=t->type.fid.inputSize; z++){ if(l==NULL){ semanticError(5,ASTroot->array[0]->t);//number of output parameters noTraverse=1; break; } if(t->type.fid.input[z]!=findTypeVar(l->array[0])){ semanticError(14,ASTroot->array[0]->t);//type Mismatch noTraverse=1; break; } l=l->array[1]; } break; case 11://else stmt S[counter]=createSymbolTable(size, topSymbolStack(symbolStack),"ELSE"); pushSymbolStack(S[counter],symbolStack); p=1; counter++; break; case 26:if(ASTroot->array[0]->label==67){ t=getSymbolTableNode(ASTroot->array[1]); t->type.id.initialized=1; } case 27: break; case 28: break; //it should not come case 29: break; case 30: break; case 31://declaration stmt InsertSymbolTable(topSymbolStack(symbolStack), ASTroot); return; break; case 51://Assignment noTraverse=1; typeCounter=-1; if(ASTroot->array[1]->label==3){//function call statement if(ASTroot->array[0]->label==54){//single list if(outputCheck1(ASTroot->array[0])==0)//send leaf directly return; //1- it should already have been declared, 2-if so, then it's type should be recorded } else{ //send l if(outputCheck(ASTroot->array[0])==0) return; } semantics(ASTroot->array[1]); } if(ASTroot->array[1]->label==60){//size stmt //1- check if ID is declared, 2- What is the type of ID, 3- Compare with the return type if(!isDeclared(ASTroot->array[1]->array[0])){ semanticError(1,ASTroot->array[1]->array[0]->t); return; } z=findType(ASTroot->array[1]->array[0],0); if(z==57){ if(outputCheck(ASTroot->array[0])==0){//it will populate type of LHS if declared, else returns 0 return; } else{//declared if(!(typeCounter==0&&type[0]==57)) semanticError(6,ASTroot->array[0]->t); return; } } else if(z==58){ if(outputCheck(ASTroot->array[0])==0){//it will populate type of LHS if declared, else returns 0 return; } else{//declared if(!(typeCounter==1&&type[0]==55&&type[1]==55)) semanticError(6,ASTroot->array[0]->t); return; } } else { semanticError(8,ASTroot->array[1]->array[0]->t);//Size contains other that String and Matrix } } if(ASTroot->array[1]->label==37){//Arithmetic Expression l=ASTroot->array[0]; z=findType(l,1); if(l->label==54){ if(z==57){ if(ASTroot->array[1]->array[1]==NULL){ if(ASTroot->array[1]->array[0]->array[1]==NULL){ if(findTypeVar(ASTroot->array[1]->array[0]->array[0])==57){//initialization StringInit(ASTroot->array[0],ASTroot->array[1]->array[0]->array[0]->t.lexeme); return; } } } } else if(z==58){//lhs is matrix firstMatrix=1; if(ASTroot->array[1]->array[1]==NULL){ if(ASTroot->array[1]->array[0]->array[1]==NULL){ if((ASTroot->array[1]->array[0]->array[0]->label)==44){//initialization MatrixInit(ASTroot->array[0],ASTroot->array[1]->array[0]->array[0]); return; } } } } } if(z==-1) break; typeCounter++; type[typeCounter]=z; if((z=findTypeAE(ASTroot->array[1]))!=type[typeCounter]){ bufToken.lineNumber=l->t.lineNumber; semanticError(10,bufToken); break; } //valid Arithmetic expression //debug(); t= getSymbolTableNode(ASTroot->array[0]); t->type.id.initialized=1; typeCounter=-1; } break; case 52://go to case 54 case 54: if(!isDeclared(ASTroot)) semanticError(1,ASTroot->t); break; case 75:// AND case 76:// OR case 77:// LT case 78:// LE case 79:// EQ case 80:// GT case 81:// GE case 82:// NE case 83:// NOTbooleanExpressionSemantics(ASTnode* BE) noTraverse=1; if(booleanExpressionSemantics(ASTroot)==0){ semanticError(10,bufToken); } default: break; }//end of switch int i; if(noTraverse==0){ for( i=0; i<ASTroot->arraySize; i++){ if(ASTroot->array[i]!=NULL){ semantics(ASTroot->array[i]); } } } if(p){ //if popping SymbolTable is a function, then check if it's output parameter are accurately initialised or not tmp=popSymbolStack(symbolStack); if(strcmp(tmp->symbolTableName,"MAIN")!=0&&strcmp(tmp->symbolTableName,"IF")!=0&&strcmp(tmp->symbolTableName,"ELSE")!=0){//it is a function int i; for(i=0; i<tmp->outputParameter; i++){ t=outputParameterInitCheck(tmp,tmp->outputParameterLexeme[i]); if(t->type.id.initialized!=1) { semanticError(13,ASTroot->array[1]->t); break; } } } } }//end of function