Пример #1
0
 def isMacroCall(self,callsite_index):
     if self.macro_inspector is None:
         return False
     if self.macro_inspector.project_dir is None:
         return False
     print "Checking Macro Call..."
     print "UPPER:",self.l[callsite_index]
     print "CALLINFO:",self.l[callsite_index+1]
     for m in re.finditer(Syntax.lt+Syntax.identifier+Syntax.water+r"\(",self.l[callsite_index].codestr):
         funcname=m.group().rstrip("(").strip()
         if Syntax.isKeyWord(funcname):
             continue
         #Note that the second argument of getExpanded is the line_num of the call site code.
         #So should be callsite_index+1
         print "Find Macro Call:",self.l[callsite_index]
         filename=self.l[callsite_index].get_func_call_info().get_file_name()
         linenum=self.l[callsite_index].get_linenum()
         print filename,linenum
         expanded_str=self.macro_inspector.getExpanded(filename,linenum)
         if expanded_str is None:
             return False
         print "expanded str:",expanded_str
         if "temp = (((abfd)->xvec->_bfd_check_format[(int) ((abfd)->format)]) (abfd));" in expanded_str:
             print "Find IT!"
         call_patttern=Syntax.lt+Syntax.identifier+Syntax.water+r"[\)\]]*"+Syntax.water+r"\("
         for m in re.finditer(call_patttern,expanded_str):
             if ']' in m.group():
                 return True
             cleaner=''.join(m.group().split())
             clean=cleaner.rstrip('(').rstrip(')')
             if not Syntax.isKeyWord(clean) and not Syntax.isLibFuncName(m.group(1)):
                 return True
     return False
Пример #2
0
 def isMacroCall(self,callsite,filename,callinfo):
     if self.macro_inspector is None:
         return False
     if self.macro_inspector.project_dir is None:
         return False
     for m in re.finditer(Syntax.lt+Syntax.identifier+Syntax.water+r"\(",callsite.codestr):
         funcname=m.group().rstrip("(").strip()
         if Syntax.isKeyWord(funcname):
             continue
         #Note that the second argument of getExpanded is the line_num of the call site code.
         #So should be callsite_index+1
         #filename=callsite.get_func_call_info().get_file_name()
         linenum=callsite.get_linenum()
         expanded_str=self.macro_inspector.getExpanded(filename,linenum)
         if expanded_str is None:
             return False
         call_patttern=Syntax.lt+Syntax.identifier+Syntax.water+r"[\)\]]*"+Syntax.water+r"\("
         for m in re.finditer(call_patttern,expanded_str):
             if ']' in m.group():
                 return True
             cleaner=''.join(m.group().split())
             clean=cleaner.rstrip('(').rstrip(')')
             if not Syntax.isKeyWord(clean) and not Syntax.isLibFuncName(m.group(1)):
                 return True
     return False    
Пример #3
0
 def isLeftPropagate(self,v,codestr):
     declare_pat=Syntax.declaration_left_propagate_pattern(v)
     variable_pat=Syntax.variable_left_propagate_pattern(v)
     print "Left Propagation Pattern:\n",declare_pat,'\n',variable_pat
     vp_m=re.search(variable_pat,codestr)
     if vp_m:
         return vp_m
     else:
         dp_m=re.search(declare_pat,codestr)
         if dp_m:
             return dp_m
         else:
             return None
Пример #4
0
 def handleReturnAssgin(self,job_trace_index,i,accesspattern,var):
     if i+2+1<len(self.l) and isinstance(self.l[i+1],FunctionCallInfo) and isinstance(self.l[i+2],LineOfCode):
         if self.l[i+1].get_func_name().split("::")[-1].strip() in self.l[i].codestr or self.isMacroCall(i):
             indexes=self.slice_same_func_lines(i+2, job_trace_index)
             count=0
             print "accesspattern:",accesspattern
             for idx in indexes[::-1]:
                 print "Line Under Check:", aIndex, "#",self.l[aIndex]
                 if 'return ' in self.l[idx].codestr:
                     self.TG.linkExpandEdges(job_trace_index,idx,"return dependency:"+var.simple_access_str())
                     #self.TG.linkTraverseEdges(i,idx,"ref:"+var.simple_access_str())
                     start=re.search(r'return\s*',self.l[idx].codestr).span()[1]
                     rightpart=self.l[idx].codestr[start:].strip().rstrip(';').strip()
                     if Syntax.isUniqueNonLibCall(rightpart):
                         jobs=self.handleReturnAssgin(job_trace_index,idx,accesspattern,var)
                         return self.taintUp(jobs)
                     else:
                         variable_pat=re.compile('^'+Syntax.variable+'$')
                         m=variable_pat.match(rightpart)
                         if m:
                             rfl,p=accesspattern
                             return self.taintUp([TaintJob(idx,TaintVar(rightpart,p,rfl))])
                         else:
                             taint_v_strs = Filter.expression2vars(rightpart)
                             jobs=map(lambda x : TaintJob(idx,x),[TaintVar(tv,[]) for tv in taint_v_strs])
                             return self.taintUp(jobs)
                 count+=1
                 if count == 3:break
             return []
     print "Fatal Error! the malformed call detail lines after return value assignment!"  
     print 1/0            
Пример #5
0
def indent(indentLevel):

    if not isinstance(indentLevel, int) or indentLevel < 1:
        raise Exception("Indent level must be a positive integer.")

    syntax = Syntax()

    return syntax.indent * indentLevel
Пример #6
0
 def getDefs(self,pairs,indexes,uppdefindex=-1):
     if indexes==[]:#BUG:please check this situation
         return []
     if uppdefindex==-1:
         uppdefindex=indexes[0]-1
     defs=[]
     for index,v,left_propa,up,low in pairs[::-1]:
         if isinstance(self.l[index],LineOfCode) and index<=uppdefindex:continue
         #note that the index of downward tainting param pointer should be set to the first code line
         #Or it will be aborted as it matched the "=".
         if indexes[low-1]<=uppdefindex:continue
         for i in indexes[up:low][::-1]:
             print "getDefs():Checking Def:",self.l[i]
             access=v.accessStr()
             if re.search(access, self.l[i].codestr):
                 maybe_def=True
             else:
                 maybe_def=False
                 pointerstr=v.pointerStr()
                 if pointerstr is not None:
                     if re.search(pointerstr, self.l[i].codestr):
                         maybe_def=True
                 
             if maybe_def:
                 def_type=self.matchDefinitionType(i,v)
                 #if def_type==Syntax.FOR or def_type==Syntax.NORMAL_ASSIGN or def_type==Syntax.OP_ASSIGN or def_type==Syntax.INC or def_type==Syntax.RAW_DEF or def_type==Syntax.SYS_LIB_DEF:#ASSIGN
                 if def_type!=Syntax.NODEF:
                     defs.append((i,v))
                     print "Find the 100% definition."
                     break
                 elif self.likeArgDef(v,self.l[i].codestr):
                     print "Check Possible Definitions:",self.l[i]
                     if isinstance(self.l[i+1],FunctionCallInfo):
                         if Syntax.isPossibleArgumentDefinition(self.l[i],v):
                             defs.append((i,v))
                             print "Yes,it is Possible Definitions."
                             print "But just possible,maybe 10%. We should continue search at least another 100% definition for assurance."
             elif self.likeArgDef(v,self.l[i].codestr):
                 print "Check Possible Definitions:",self.l[i]
                 if isinstance(self.l[i+1],FunctionCallInfo):
                     if Syntax.isPossibleArgumentDefinition(self.l[i],v):
                         defs.append((i,v))
                         print "Yes,it is Possible Definitions."
                         print "But just possible,maybe 10%. We should continue search at least another 100% definition for assurance."
     defs.sort(key=lambda x:x[0],reverse=True)#index reversed order
     return defs
Пример #7
0
 def macro_call_right_str(self,upperIndex):
     filename=self.l[upperIndex].get_func_call_info().get_file_name()
     linenum=self.l[upperIndex].get_linenum()
     print filename,linenum
     expanded_str=self.macro_inspector.getExpanded(filename,linenum)
     print "expanded str:",expanded_str
     if "temp = (((abfd)->xvec->_bfd_check_format[(int) ((abfd)->format)]) (abfd));" in expanded_str:
         print "Find It!"
     call_patttern=Syntax.lt+Syntax.identifier+Syntax.water+r"[\)\]]*"+Syntax.water+r"\("
     for m in re.finditer(call_patttern,expanded_str):
         print "matched candidate function name:",m.group(1)
         if not Syntax.isKeyWord(m.group(1)) and not Syntax.isLibFuncName(m.group(1)):
             span=m.span()
             #FIX ME this is wrong when handling cases like: MAZE(a,b)-->'call1(a)+call2(b)".
             #Then when handling the second call site, it returns 'a' as the detected argument.  
             return expanded_str[span[1]:]
     print "Fatal Error treat 'sizeof' as a function call or other ERROR!! Please check the macro_call_right_str()"
     x=1/0
Пример #8
0
	def __parseNameRequirementsPredicates(self, planningDomainFile):
		#~ Predicates are defined in the usual PDDL way:
		#~ (:predicates
			#~ (C ?x)
			#~ (P ?x ?y)
			#~ ...
		#~ )
		
		syntax = Syntax()
		
		#~ A concept is composed by a name and only one variable, e.g. C ?x
		#~ We remove the variable and replace it with the keyword "Concept"
		pddlConcept =  Group(syntax.allowed_word.setResultsName("predicateName") + syntax.variable.setParseAction(replaceWith("Concept")).setResultsName("predicateType"))
		#~ A role is composed by a name and exactly two variables, e.g. P ?x ?y
		#~ We remove the first variable and replace it with the keyword "Role"
		#~ while we remove completely the second
		pddlRole = Group(syntax.allowed_word.setResultsName("predicateName") + \
					syntax.variable.setParseAction(replaceWith('Role')).setResultsName("predicateType")  + \
					syntax.variable.setParseAction().suppress() ) 
		#~ We put pddlVariable.setParseAction() in order to remove the effect of the previous pddlVariable.setParseAction(replaceWith('Role'))
		#~ If we fail to do so, then all the times we use self.variable, it will be substituted by the word "Role"
		
		#~ A PDDL Predicate is either concepts or roles
		pddlPredicate = pddlConcept ^ pddlRole
		pddlPredicates = syntax.leftPar + syntax.pddlPredicatesTag.suppress() + Group(OneOrMore(syntax.leftPar + pddlPredicate + syntax.rightPar)).setResultsName("predicates") + syntax.rightPar
		
		
		pddlDomain = StringStart() + \
					syntax.leftPar + syntax.pddlDefineTag + \
					syntax.leftPar + syntax.pddlDomainTag + \
					syntax.pddlDomainName.setResultsName("domainName") + \
					syntax.rightPar + \
					syntax.pddlRequirements.suppress() + \
					pddlPredicates + \
					Regex("(.*\r*\n*)*\)\r*\n*").suppress()
		
		#~ Parse the file
		result = pddlDomain.parseFile(planningDomainFile)
		
		self.__domainName = result["domainName"] #Save the domain name
		
		#~ Save the concepts and roles
		for predicate in result["predicates"]:
			
			#~ If a predicate has the same name as a keyword (e.g., "exists", "not", etc.), raise an Exception
			if str(predicate["predicateName"]) in syntax.keywords:
				raise Exception("It is not possible to use the word \"" + str(predicate["predicateName"]) + "\" as a name for a predicate, as it is a keyword.")
				
			if predicate["predicateType"][0] == "Concept":
				self.__concepts.add(str(predicate["predicateName"]))
				self.__conceptsParse = self.__conceptsParse ^ Literal(str(predicate["predicateName"]))
			else:
				self.__roles.add(str(predicate["predicateName"]))
				self.__rolesParse = self.__rolesParse ^ Literal(str(predicate["predicateName"]))
Пример #9
0
	def __parseAssertion(self, assertionToParse, conceptList, roleList, individualList):
		syntax = Syntax()
		
		#~ If assertionToParse is a string, we parse it by considering the parenthesis that close every expression
		#~ and analyse the resulting pyparsing.ParseResults.
		#~ If axiomToParse is already a pyparsing.ParseResults (or a list, or a tuple), then we analise it directly.
		if isinstance(assertionToParse, str):
			raise Exception("Sorry, at the moment we can't parse assertions that are passed as a string.\n" + assertionToParse)
		
		#~ If assertionToParse is either a ParseResults, tuple, or list, then it must have
		#~ 2 or 3 elements, and all of them must be strings.
		#~ Also, if it has 2 elements, then the first element must be in conceptList (if specified),
		#~ while if it has 3 elements, it must be in roleList (if specified)
		if len(assertionToParse) < 2 or len(assertionToParse) > 3:
			raise Exception("An assertion must be formed of 2 elements (in case of an assertion involving a concept), or 3 (in case of a role).\n" + \
					"The following assertion has instead " + str(len(assertionToParse)) + " elements:\n" + \
					str(assertionToParse))
		
		if not all(isinstance(element, str) for element in assertionToParse):
			raise Exception("The element composing an assertion to parse must be all strings.\n" + str(assertionToParse))
		
		if len(assertionToParse) == 2:
			if not self.__checkConcept(assertionToParse[0], conceptList):
				raise Exception("The term used in the assertion is not a valid concept.\n" + str(assertionToParse))
			
			if not self.__checkIndividual(assertionToParse[1], individualList):
				raise Exception("The individual used in the assertionis not a individual.\n" + str(assertionToParse))
			
			#~ Save the elements
			self.__term = assertionToParse[0]
			self.__individual1 = assertionToParse[1]
		
		elif len(assertionToParse) == 3:
			if not self.__checkRole(assertionToParse[0], roleList):
				raise Exception("The term used in the assertion is not a valid concept.\n" + str(assertionToParse))
			
			if not self.__checkIndividual(assertionToParse[1], individualList):
				raise Exception("The individual used in the assertionis not a individual.\n" + str(assertionToParse))
			
			if not self.__checkIndividual(assertionToParse[2], individualList):
				raise Exception("The individual used in the assertionis not a individual.\n" + str(assertionToParse))
			
			#~ Save the elements
			self.__term = assertionToParse[0]
			self.__individual1 = assertionToParse[1]
			self.__individual2 = assertionToParse[2]
		
		else:
				#~ Something is wrong.
				raise Exception("Something went wrong with the analisys of the following assertion.\n" + str(assertionToParse))
Пример #10
0
	def __checkConcept(self, term, conceptList):
		#~ Checks if term is a valid concept.
		#~ term must not be a reserved keyword,
		#~ and must be in conceptList
		#~ Returns True if it is valid, False otherwise
		
		if not isinstance(term, str):
			raise Exception("The term passed to the function __checkConcept must be a string: " + str(type(term)))
		
		syntax = Syntax()
		
		#~ The term can't be a reserved keyword
		if term in syntax.keywords:
			return False
			
		if not term in conceptList:
			return False
		
		return True
Пример #11
0
	def __parseProblem(self, planningProblemFile):
		#~ The parsing is divided in parts:
		#~ - retrieve the domain name and check that the requirements and the predicates are ok. If not, raise an exception.
		#~ 		From the predicates we create the list of concepts and roles;
		#~ - read the file again to retrieve the axioms, the condition-action rules, and the actions.
		
		syntax = Syntax()
		
		#~ The domain specified in the problem must be the same name specified in the domain parsed before.
		#~ For this reason we put Literal(self.__domainName)
		pddlProblem = StringStart() + \
					syntax.leftPar + syntax.pddlDefineTag + \
					syntax.leftPar + syntax.pddlProblemTag + syntax.pddlProblemName.setResultsName("problemName") + syntax.rightPar + \
					syntax.leftPar + syntax.pddlProblemDomainTag + Literal(self.__domainName) + syntax.rightPar + \
					syntax.leftPar + syntax.pddlProblemObjectsTag + Group(OneOrMore(syntax.pddlProblemObject)).setResultsName("problemObjects") + syntax.rightPar + \
					syntax.leftPar + syntax.pddlProblemInitTag + Group(OneOrMore(nestedExpr())).setResultsName("problemAssertions") + syntax.rightPar + \
					syntax.leftPar + syntax.pddlProblemGoalTag + nestedExpr().setResultsName("problemGoal") + syntax.rightPar + \
					syntax.rightPar + \
					StringEnd()
		
		#~ Parse the file
		result = pddlProblem.parseFile(planningProblemFile)
		
		self.__problemName = result["problemName"] #Save the problem name
		
		#~ Save the individuals.
		#~ In PDDL they are reffered to as objects.
		for obj in result["problemObjects"]:
			self.__individuals.add(obj)
		
		#~ Save the assertions.
		for assertion in result["problemAssertions"]:
			self.__assertions.add(Assertion(assertion, self.__concepts, self.__roles, self.__individuals))
		
		#~ Save the goal query.
		self.__goalQuery = ECQ(result["problemGoal"][0], self.__concepts, self.__roles, self.__individuals)
		
		#~ Check that the goal query is boolean
		if len(self.__goalQuery.freeVars()) > 0:
			raise Exception("The goal query must be boolean.")
Пример #12
0
 def matchDefinitionType(self,i,var):
     codestr=self.l[i].codestr
     if var.v=='i':
         print "GotIt!!"
     access=var.accessStr()
     print "Checking Definition Type for:",access
     print "codestr:",codestr
     
     if Syntax.isForStatement(codestr,access):
         return Syntax.FOR
     if Syntax.isIncDef(var.v, codestr):
         return Syntax.INC
     
     #inc operation detection must be before the assignment.
     #because when detecting variable (i) in case such as: "for (int i=-1;i<m;i++){",
     #INC result must be returned as ForJobGenerator is only called in handle branch of INC operation
     #in "lastModification" and "CheckingArgDefinition" function.
     #This weird behavior need be fixed in future. 
     
     normal_assginment=Syntax.normal_assignment_pattern(access)
     match=re.search(normal_assginment,codestr)
     if match:
         rightstr=codestr[match.span()[1]:].rstrip(';')
         if Syntax.isUniqueNonLibCall(rightstr):
             if i+2+1<len(self.l) and isinstance(self.l[i+1],FunctionCallInfo) and isinstance(self.l[i+2],LineOfCode):
                 if self.l[i+1].get_func_name().split("::")[-1].strip() in self.l[i].codestr:
                     return Syntax.RETURN_VALUE_ASSIGN
                 elif self.isMacroCall(i):
                     return Syntax.RETURN_VALUE_ASSIGN
         return Syntax.NORMAL_ASSIGN
     op_assignment=Syntax.op_assignment_pattern(access)
     if re.search(op_assignment,codestr):
         return Syntax.OP_ASSIGN
     raw_definition=r"^\s*\{\s*[A-Za-z_][A-Za-z0-9_]+\s+(\*\s*)*([A-Za-z_][A-Za-z0-9_]+\s*,\s*)*"+var.v+"\s*;"
     if re.search(raw_definition, codestr):
         print "We got the raw definition!",codestr
         return Syntax.RAW_DEF
     if Syntax.isLibArgDef(var,codestr):
         return Syntax.SYS_LIB_DEF
     return  Syntax.NODEF
Пример #13
0
	def __parseAxiom(self, axiomToParse, conceptList, roleList):
		
		#~ (isA  above     :topC     )
		#~ (isA  above  (not (exists   (inverse next ))   )  )
		#~ (isA  (exists  next ) (not (exists reachable-floor)  )  )
		#~ (isA next (not reachable-floor))
		#~ (funct (inverse next ))
		
		syntax = Syntax()
		
		#~ If axiomToParse is a string, we parse it by considering the parenthesis that close every expression
		#~ and analyse the resulting pyparsing.ParseResults.
		#~ If axiomToParse is already a pyparsing.ParseResults (or a list, or a tuple), then we analise it directly.
		result = None
		if isinstance(axiomToParse, str):
			raise Exception("Sorry, at the moment we can't parse axioms that are passed as a string.\n" + axiomToParse)
		
		elif isinstance(axiomToParse, (ParseResults, tuple, list)):
			result = axiomToParse
			
		if isinstance(result[0], str) and result[0] == syntax.isA:
			#~ We have either a positive or negative axiom, for sure not a functional one
			
			#~ Parse the first term
			if isinstance(result[1], str):
				#~ The first term is either an atomic concept A or atomic role P
				
				if not (self.__checkConcept(result[1], conceptList) or self.__checkRole(result[1], roleList)):
					raise Exception("The term \"" + result[1] + "\" is not valid, it can't be used to build the following axiom:\n" + str(result))
				
				self.__leftTerm = result[1]
			
			elif isinstance(result[1], (ParseResults, tuple, list)):
				
				if isinstance(result[1][0], str) and result[1][0] == syntax.exists:
					
					if isinstance(result[1][1], str):
						#~ It's the term: exists P
						
						if not self.__checkRole(result[1][1], roleList):
							#~ The term is in neither lists
							raise Exception("The term \"" + result[1][1] + "\" used for the following axiom is not a valid role.\n" + str(result))
							
						self.__leftTerm = result[1][1]
						self.__leftTermExists = True
					
					elif isinstance(result[1][1], (ParseResults, tuple, list)) and \
						isinstance(result[1][1][0], str) and result[1][1][0] == syntax.inverse and \
						isinstance(result[1][1][1], str):
						#~ It's the term: exists P^-
						
						if not self.__checkRole(result[1][1][1], roleList):
							#~ The term is in neither lists
							raise Exception("The term \"" + result[1][1][1] + "\" used for the following axiom is not a valid role.\n" + str(result))
							
						
						self.__leftTerm = result[1][1][1]
						self.__leftTermExists = True
						self.__leftTermInverse = True
					
					else:
						#~ Something is wrong.
						raise Exception("The left term of the following axiom was not recognized as a valid one.\n" + str(result))
					
				elif isinstance(result[1][0], str) and result[1][0] == syntax.inverse and \
					isinstance(result[1][1], str):
					#~ It's the term: P^-
					
					if not self.__checkRole(result[1][1], roleList):
						#~ The term is in neither lists
						raise Exception("The term \"" + result[1][1] + "\" used for the following axiom is not a valid role.\n" + str(result))
							
					self.__leftTerm = result[1][1]
					self.__leftTermInverse = True
				
				else:
					#~ Something is wrong.
					raise Exception("The left term of the following axiom was not recognized as a valid one.\n" + str(result))
			
			else:
				#~ Something is wrong.
				raise Exception("The left term of the following axiom was not recognized as a valid one.\n" + str(result))
			
			#~ Parse the second term
			if isinstance(result[2], str):
				#~ The second term is either an atomic concept A or atomic role P
				
				if not (self.__checkConcept(result[2], conceptList) or self.__checkRole(result[2], roleList)):
					raise Exception("The term \"" + result[2] + "\" is not valid, it can't be used to build the following axiom:\n" + str(result))
				
				if self.__checkConcept(self.__leftTerm, conceptList) and self.__checkRole(result[2], roleList):
					raise Exception("The term \"" + result[2] + "\" is a role, while \"" + self.__leftTerm + "\" is a concept.\nIt can't be used to build the following axiom:\n" + str(result))
					
				if not self.__leftTermExists and \
					self.__checkRole(self.__leftTerm, roleList) and \
					not self.__checkRole(result[2], roleList):
					raise Exception("The term \"" + result[2] + "\" is not a role, while \"" + self.__leftTerm + "\" is.\nIt can't be used to build the following axiom:\n" + str(result))
					
				self.__rightTerm = result[2]
			
			elif isinstance(result[2], (ParseResults, tuple, list)):
				
				if isinstance(result[2][0], str) and result[2][0] == syntax.exists:
					
					if isinstance(result[2][1], str):
						#~ It's the term: exists P
						
						if not self.__checkRole(result[2][1], roleList):
							raise Exception("The term \"" + result[2][1] + "\" is not a valid role, it can't be used to build the following axiom:\n" + str(result))
						
						#~ If the first term is either P or P^-, then we raise an Exception
						if not self.__leftTermExists and self.__checkRole(self.__leftTerm, roleList):
							raise Exception("The term \"" + result[2][1] + "\" is not a concept, while \"" + self.__leftTerm + "\" is.\nIt can't be used to build the following axiom:\n" + str(result))
						
						self.__rightTerm = result[2][1]
						self.__rightTermExists = True
					
					elif isinstance(result[2][1], (ParseResults, tuple, list)) and \
						isinstance(result[2][1][0], str) and result[2][1][0] == syntax.inverse and \
						isinstance(result[2][1][1], str):
						#~ It's the term: exists P^-
						
						if not self.__checkRole(result[2][1][1], roleList):
							raise Exception("The term \"" + result[2][1][1] + "\" is not a valid role, it can't be used to build the following axiom:\n" + str(result))
						
						#~ If the first term is either P or P^-, then we raise an Exception
						if not self.__leftTermExists and self.__checkRole(self.__leftTerm, roleList):
							raise Exception("The term \"" + result[2][1][1] + "\" is not a concept, while \"" + self.__leftTerm + "\" is.\nIt can't be used to build the following axiom:\n" + str(result))
							
						self.__rightTerm = result[2][1][1]
						self.__rightTermExists = True
						self.__rightTermInverse = True
					
					else:
						#~ Something is wrong.
						raise Exception("The right term of the following axiom was not recognized as a valid one.\n" + str(result))
					
				elif isinstance(result[2][0], str) and result[2][0] == syntax.inverse and \
					isinstance(result[2][1], str):
					#~ It's the term: P^-
					
					if not self.__checkRole(result[2][1], roleList):
						raise Exception("The term \"" + result[2][1] + "\" is not a valid role, it can't be used to build the following axiom:\n" + str(result))
					
					#~ If the first term is either P or P^-, then we raise an Exception
					if not self.__leftTermExists and self.__checkRole(self.__leftTerm, roleList):
						raise Exception("The term \"" + result[2][1] + "\" is not a concept, while \"" + self.__leftTerm + "\" is.\nIt can't be used to build the following axiom:\n" + str(result))
						
					self.__rightTermTerm = result[2][1]
					self.__rightTermInverse = True
				
				elif isinstance(result[2][0], str) and result[2][0] == syntax.neg:
					#~ The axiom is a disjunction
					self.__disjoint = True
					
					if isinstance(result[2][1], str):
						#~ The second term is either an atomic concept A or atomic role P
						
						if not (self.__checkConcept(result[2][1], conceptList) or self.__checkRole(result[2][1], roleList)):
							raise Exception("The term \"" + result[2][1] + "\" is not valid, it can't be used to build the following axiom:\n" + str(result))
						
						if (self.__checkConcept(self.__leftTerm, conceptList) or \
							(self.__leftTermExists and self.__checkRole(self.__leftTerm, roleList))) and \
							not self.__checkConcept(result[2][1], conceptList):
							raise Exception("The term \"" + result[2][1] + "\" is not a concept, while \"" + self.__leftTerm + "\" is.\nIt can't be used to build the following axiom:\n" + str(result))
							
						if self.__checkRole(self.__leftTerm, roleList) and not self.__checkRole(result[2][1], roleList):
							raise Exception("The term \"" + result[2][1] + "\" is not a role, while \"" + self.__leftTerm + "\" is.\nIt can't be used to build the following axiom:\n" + str(result))
						
						self.__rightTerm = result[2][1]
						
					elif isinstance(result[2][1], (ParseResults, tuple, list)):
						
						if isinstance(result[2][1][0], str) and result[2][1][0] == syntax.exists:
						
							if isinstance(result[2][1][1], str):
								#~ It's the term: exists P
								
								if not self.__checkRole(result[2][1][1], roleList):
									raise Exception("The term \"" + result[2][1][1] + "\" is not a valid role, it can't be used to build the following axiom:\n" + str(result))
								
								#~ If the first term is either P or P^-, then we raise an Exception
								if not self.__leftTermExists and self.__checkRole(self.__leftTerm, roleList):
									raise Exception("The term \"" + result[2][1][1] + "\" is not a concept, while \"" + self.__leftTerm + "\" is.\nIt can't be used to build the following axiom:\n" + str(result))
								
								self.__rightTerm = result[2][1][1]
								self.__rightTermExists = True
							
							elif isinstance(result[2][1][1], (ParseResults, tuple, list)) and \
								isinstance(result[2][1][1][0], str) and result[2][1][1][0] == syntax.inverse and \
								isinstance(result[2][1][1][1], str):
								#~ It's the term: exists P^-
								
								if not self.__checkRole(result[2][1][1][1], roleList):
									raise Exception("The term \"" + result[2][1][1][1] + "\" is not a valid role, it can't be used to build the following axiom:\n" + str(result))
								
								#~ If the first term is either P or P^-, then we raise an Exception
								if not self.__leftTermExists and self.__checkRole(self.__leftTerm, roleList):
									raise Exception("The term \"" + result[2][1][1][1] + "\" is not a concept, while \"" + self.__leftTerm + "\" is.\nIt can't be used to build the following axiom:\n" + str(result))
								
								self.__rightTerm = result[2][1][1][1]
								self.__rightTermExists = True
								self.__rightTermInverse = True
							
							else:
								#~ Something is wrong.
								raise Exception("The right term of the following axiom was not recognized as a valid one.\n" + str(result))
							
						elif isinstance(result[2][1][0], str) and result[2][1][0] == syntax.inverse and \
							isinstance(result[2][1][1], str):
							#~ It's the term: P^-
							
							if not self.__checkRole(result[2][1][1], roleList):
								raise Exception("The term \"" + result[2][1][1] + "\" is not a valid role, it can't be used to build the following axiom:\n" + str(result))
							
							#~ If the first term is either P or P^-, then we raise an Exception
							if not self.__leftTermExists and self.__checkRole(self.__leftTerm, roleList):
								raise Exception("The term \"" + result[2][1][1] + "\" is not a concept, while \"" + self.__leftTerm + "\" is.\nIt can't be used to build the following axiom:\n" + str(result))
							
							self.__rightTermTerm = result[2][1][1]
							self.__rightTermInverse = True
						
						else:
							#~ Something is wrong.
							raise Exception("The right term of the following axiom was not recognized as a valid one.\n" + str(result))
					
					
				else:
					#~ Something is wrong.
					raise Exception("The right term of the following axiom was not recognized as a valid one.\n" + str(result))
			
			else:
				#~ Something is wrong.
				raise Exception("The right term of the following axiom was not recognized as a valid one.\n" + str(result))
		
		elif isinstance(result[0], str) and result[0] == syntax.funct:
			#~ It's a functionality axiom
			self.__functionality = True
			
			#~ Parse the first term
			if isinstance(result[1], str):
				#~ The first term is an atomic role P
				
				if not self.__checkRole(result[1], roleList):
					raise Exception("The term \"" + result[1] + "\" is not a valid role, it can't be used to build the following axiom:\n" + str(result))
				
				self.__leftTerm = result[1]
			
			elif isinstance(result[1], (ParseResults, tuple, list)) and \
				isinstance(result[1][0], str) and result[1][0] == syntax.inverse and \
				isinstance(result[1][1], str):
				#~ The first term is: P^-
				
				if not self.__checkRole(result[1][1], roleList):
					raise Exception("The term \"" + result[1][1] + "\" is not a valid role, it can't be used to build the following axiom:\n" + str(result))
				
				self.__leftTerm = result[1][1]
				self.__leftTermInverse = True
			
			else:
				#~ Something is wrong.
				raise Exception("The following functionality axiom was not recognized as a valid one.\n" + str(result))
				
		else:
			#~ Something is wrong.
			raise Exception("The axiom was not recognized as a valid one.\n" + str(result))
Пример #14
0
    def __parseQuery(self, queryToParse, conceptList, roleList,
                     individualList):

        syntax = Syntax()

        #~ If queryToParse is a string, we parse it by considering the parenthesis that close every expression
        #~ and analyse the resulting pyparsing.ParseResults.
        #~ If queryToParse is already a pyparsing.ParseResults, then we analise it directly.
        result = None
        if isinstance(queryToParse, str):
            parser = StringStart() + nestedExpr() + StringEnd()

            result = parser.parseString(queryToParse)

            #~ We consider only the first element of result, since, if it is a valid list,
            #~ then result is a nested list, and thus result[0] is the actual list we
            #~ are interested in.
            result = result[0]

        elif isinstance(queryToParse, (ParseResults, tuple, list)):
            result = queryToParse

        #~ The expressions used to build an ECQ can be:
        #~ - "(not ECQ)"
        #~ - "(exists (vars) ECQ)"
        #~ - "(and ECQ list)"
        #~ - "(mko-eq var1 var2)"
        #~ - "(mko UCQ)"
        #~ - ":True"
        #~ We check the first element (result[0]),
        #~ which has to be a special word identifying which type of expression is used
        if result[0] == syntax.true:
            #~ The expression must be "(:True)", thus result must contain exactly 1 element
            if len(result) != 1:
                raise Exception("The expression \"(" + syntax.true +
                                ")\" must contain only the keyword " +
                                syntax.true + ".")

            #~ Set the current ECQ as True
            self.__trueQuery = True

        elif result[0] == syntax.neg:
            #~ The expression must be "(not ECQ)", thus result must contain exactly 2 elements
            if len(result) != 2:
                raise Exception(
                    "The expression \"(not ECQ )\" must contain only one ECQ.")

            self.__ecqs.add(
                ECQ(result[1], conceptList, roleList, individualList))

            #~ Set the current ECQ as negated
            self.__negated = True

        elif result[0] == syntax.exists:
            #~ The element result[1] must contain the existential variables,
            #~ while result[2] the inner ECQ.
            #~ result must contain exactly 3 elements
            if len(result) != 3:
                raise Exception(
                    "The expression \"(exists (Vars) (ECQ) )\" must contain only a set of existential variables and one ECQ."
                )

            self.__ecqs.add(
                ECQ(result[2], conceptList, roleList,
                    individualList))  # Add the ECQ

            #~ Check that variables are syntactically valid (i.e. "?"+ a valid string)
            #~ and add them to self.__existentialVars
            varName = (StringStart() +
                       syntax.variable.setResultsName("varName") +
                       StringEnd()).leaveWhitespace()
            for varString in result[1]:
                var = Variable(varName.parseString(varString)[0])
                #~ Check that var is a free variable in the inner ECQ, otherwise raise an Exception
                for ecq in self.__ecqs:
                    if not (var in ecq.freeVars()):
                        raise Exception("The variable " + str(var) +
                                        " does not appear in the inner ECQ.")

                self.__existentialVars.add(var)

        elif result[0] == syntax.queryAnd:
            #~ The list must contain "and" plus at least two inner ECQs,
            #~ starting from element result[1].
            if len(result) <= 2:
                raise Exception(
                    "The expression \"(and ... )\" must contain at least 2 internal ECQs."
                )

            for counter in range(1, len(result)):
                self.__ecqs.add(
                    ECQ(result[counter], conceptList, roleList,
                        individualList))

            #~ Check that all the inner ECQs have the same free variables
            #~ for check in combinations(self.__ecqs, 2):
            #~ print(check)
            #~ if check[0].freeVars() != check[1].freeVars():
            #~ raise Exception("The ECQs have different free variables in them!\n"+str(check[0])+"\n"+str(check[1]))

        elif result[0] == syntax.mkoEq:

            #~ This represent an equality assertion. It must contain exactly 2 variable
            #~ (thus, considering 'mko-eq', the lenght can't be more than 3).
            if len(result) != 3:
                raise Exception(
                    "An equality assertion must contain exactly 2 variables. "
                    + str(len(result[1:])) + " provided instead: " +
                    str(result[1:]))

            #~ Check that variables are syntactically valid (i.e. "?"+ a valid string)
            #~ and add them to self.__existentialVars

            varName = (StringStart() +
                       syntax.variable.setResultsName("varName") +
                       StringEnd()).leaveWhitespace()

            self.__equalityVar1 = Variable(varName.parseString(result[1])[0])
            self.__equalityVar2 = Variable(varName.parseString(result[2])[0])

            #~ The variables have to be different from each other, we don't
            #~ accept an equality of the type (= ?x ?x).
            #~ If this is the case, we raise an Exception.
            if self.__equalityVar1 == self.__equalityVar2:
                raise Exception("The variables provided in the equality statement are the same. Please adjust/remove the atom: (= ?" + \
                  str(result[1]) + " ?" + str(result[2]) + ")")

        elif result[0] == syntax.mko:
            #~ This represent an UCQ inside a minimal knowledge operator.
            #~ An UCQ must be contained between parenthesis ( ), like:
            #~ (mko (...))
            #~ even if the UCQ is a single atom, so result is like:
            #~ ['mko', [...]]
            #~ thus result can't contain more than two elements.
            if len(result) > 2:
                raise Exception(
                    "A minimal knowledge operator axiom should contain only an UCQ between parenthesys \"()\"."
                )

            self.__ucq = UCQ(result[1], conceptList, roleList, individualList)

        else:
            raise Exception("No valid word found: " + str(result[0]))

        #~ Find the freeVars of the current ECQ.
        #~ To do so, we collect all the free vars appearing in the inner ECQs,
        #~ or in the UCQ, and remove the one that are set as existential
        #~ in the current ECQ.
        #~ If the current ECQ is an equality, we consider the variables involved
        #~ as free variables.
        for ecq in self.__ecqs:
            self.__freeVars.update(ecq.freeVars())

        if not self.__ucq is None:
            self.__freeVars.update(self.__ucq.freeVars())

        if isinstance(self.__equalityVar1, Variable):
            self.__freeVars.add(self.__equalityVar1)
        if isinstance(self.__equalityVar2, Variable):
            self.__freeVars.add(self.__equalityVar2)

        self.__freeVars = self.__freeVars.difference(self.__existentialVars)
Пример #15
0
	def __parseAxiomsRulesActions(self, planningDomainFile):
		#~ The functions parse the following elements:
			#~ - axioms
			#~ - condition-action rules
			#~ - actions
		
		#~ The possible axioms, as defined in DL-Lite, are (here written in PDDL-EKab syntax):
			#~ (isA pddlBasicRole pddlGeneralRole)
			#~ (isA pddlBasicConcept pddlGeneralConcept)
			#~ (funct pddlBasicRole)
		#~ The possible terms participating in axioms are, instead:
			#~ pddlAtomicRole := nome del ruolo definito in predicates
			#~ pddlBasicRole := pddlAtomicRole | (inverse pddlAtomicRole)
			#~ pddlGeneralRole := pddlBasicRole | (not pddlBasicRole)
			#~ pddlAtomicRole := nome del concetto definito in predicates
			#~ pddlBasicConcept := pddlAtomicRole | (exists pddlBasicRole)
			#~ pddlGeneralConcept := pddlBasicConcept | (not pddlBasicConcept) | (existsQualified pddlBasicRole pddlBasicConcept) | topC
		#~ 
		#~ The parser divides immediately the axioms in: positive axioms, negative axioms, and functionality axioms
		
		syntax = Syntax()
		
		pddlAtomicRole = self.__rolesParse
		pddlAtomicConcept = self.__conceptsParse
		
		pddlBasicRole = pddlAtomicRole ^ Group((syntax.leftPar + Literal(syntax.inverse) + pddlAtomicRole + syntax.rightPar))
		pddlBasicConcept = pddlAtomicConcept ^ Group((syntax.leftPar + Literal(syntax.exists) +  pddlBasicRole + syntax.rightPar))
		
		pddlGeneralConcept = syntax.topC ^ \
					Group((syntax.leftPar + Literal(syntax.existsQualified) + pddlBasicConcept + pddlBasicRole + syntax.rightPar)) ^ \
					pddlBasicConcept
		#~ pddlGeneralRole = Group((self.leftPar + "not" + pddlBasicRole + self.rightPar)) ^ \
		#~			pddlBasicRole
		
		pddlAxiomPos = Group(\
					Empty().setParseAction(replaceWith("AxiomPos")) + \
					Group(((syntax.isA + pddlBasicConcept + pddlGeneralConcept) ^ (syntax.isA + pddlBasicRole + pddlBasicRole))) \
					)
		pddlAxiomNeg = Group( \
					Empty().setParseAction(replaceWith("AxiomNeg")) + \
					Group(((syntax.isA + pddlBasicConcept + syntax.leftPar + Literal(syntax.neg).suppress() +  pddlBasicConcept + syntax.rightPar) ^ \
					(syntax.isA + pddlBasicRole + syntax.leftPar + Literal(syntax.neg).suppress() + pddlBasicRole + syntax.rightPar)) \
					))
		pddlAxiomFunct = Group(Empty().setParseAction(replaceWith("AxiomFunct")) + Literal(syntax.funct).suppress() + pddlBasicRole)
		
		#~ pddlAxioms = syntax.leftPar + syntax.pddlAxiomsTag + \
				#~ Group(OneOrMore(syntax.leftPar + (pddlAxiomPos ^ pddlAxiomNeg ^ pddlAxiomFunct) + syntax.rightPar)).setResultsName("axioms") + syntax.rightPar
		
		pddlAxioms = syntax.leftPar + syntax.pddlAxiomsTag + \
				Group(OneOrMore(nestedExpr())).setResultsName("axioms") + syntax.rightPar
		
		#~ A condition-action rule has the form of:
			#~ ECQ -> action name
		#~ This, in the PDDL-EKab sytax is expressed as:
			#~ (:rule rule-name
				#~ :condition ECQ
				#~ :action action-name
			#~ )
		pddlRuleName = syntax.allowed_word.setResultsName("ruleName") # Rule name
		pddlRuleCondition = syntax.pddlRuleConditionTag + nestedExpr().setResultsName("ruleCondition")
		pddlRuleAction = syntax.pddlRuleActionTag + syntax.allowed_word.setResultsName("ruleAction")
		pddlRule = Group(syntax.leftPar + syntax.pddlRuleTag + pddlRuleName + pddlRuleCondition + pddlRuleAction + syntax.rightPar)
		pddlRules = Group(ZeroOrMore(pddlRule)).setResultsName("rules")
		
		#~ An action has the form of:
			#~ name (input parameters): { list of effects }
		#~ Each effect has the form:
			#~ ECQ ~> add F+, del F-
		#~ where F+ and F- are a set of atomic effects.
		#~ This, in the PDDL-EKab sytax is expressed as:
			#~ (:action action-name
				#~ :parameters ( list of variables )
				#~ :effects (
					#~ :condition ECQ
					#~ :add (atoms list)
					#~ :remove (atoms list)
					#~ )
					#~ ...
					#~ (
					#~ :condition ECQ
					#~ :add (atoms list)
					#~ :delete (atoms list)
					#~ )
			#~ )
		pddlActionName = syntax.allowed_word.setResultsName("actionName")
		pddlActionParameters = Literal(":parameters").suppress() + syntax.leftPar + Group(ZeroOrMore(syntax.variable)).setResultsName("actionParameters") + syntax.rightPar
		
		pddlActionEffectCondition = syntax.pddlActionEffectConditionTag + nestedExpr().setResultsName("effectCondition")
		pddlActionEffectAdd = syntax.pddlActionEffectAddTag + nestedExpr().setResultsName("effectAdd")
		pddlActionEffectDel = syntax.pddlActionEffectDelTag + nestedExpr().setResultsName("effectDelete")
		pddlActionEffect = Group(syntax.leftPar + pddlActionEffectCondition + pddlActionEffectAdd + syntax.rightPar) ^ \
							Group(syntax.leftPar + pddlActionEffectCondition + pddlActionEffectDel + syntax.rightPar) ^ \
							Group(syntax.leftPar + pddlActionEffectCondition + pddlActionEffectAdd + pddlActionEffectDel + syntax.rightPar)
		pddlActionEffects = syntax.pddlActionEffectsTag + Group(OneOrMore(pddlActionEffect)).setResultsName("actionEffects")
		
		pddlAction = Group(syntax.leftPar + syntax.pddlActionTag + pddlActionName + pddlActionParameters + pddlActionEffects + syntax.rightPar)

		pddlActions = Group(ZeroOrMore(pddlAction)).setResultsName("actions")
		
		#~ The section (:predicates ...) is matched by the Regex expression:
		#~ Regex("\(\s*\:predicates\s*\r*\n*(\s*\(.*\)\s*\r*\n*)*\s*\)").suppress()
		pddlDomain = StringStart() + \
					syntax.leftPar + syntax.pddlDefineTag + \
					syntax.leftPar + syntax.pddlDomainTag + \
					Literal(self.__domainName).suppress() + syntax.rightPar + \
					syntax.pddlRequirements.suppress() + \
					Regex("\(\s*\:predicates\s*\r*\n*(\s*\(.*\)\s*\r*\n*)*\s*\)").suppress() + \
					pddlAxioms + \
					pddlRules + \
					pddlActions + \
					syntax.rightPar + \
					StringEnd()
		
		#~ Parse the file
		try:
			result = pddlDomain.parseFile(planningDomainFile)
		except ParseException as x:
			print ("Line {e.lineno}, column {e.col}:\n'{e.line}'".format(e=x))
			raise
			
		#~ 
		#~ Analyse the axioms
		#~ 
		for axiomParse in result["axioms"]:
			
			axiom = Axiom(axiomParse, self.__concepts, self.__roles)
			
			if axiom.disjoint():
				self.__axiomsNeg.add(axiom)
			elif axiom.functionality():
				self.__axiomsFunct.add(axiom)
			else:
				self.__axiomsPos.add(axiom)
		
		#~ 
		#~ Analyse the rules
		#~ 
		for rule in result["rules"]:
			
			#~ Check that no other action has the same name
			for otherRule in result["rules"]:
				if rule != otherRule and str(rule["ruleName"]) == str(otherRule["ruleName"]):
					raise Exception("There are two rule with the same name: " + str(rule["ruleName"]))
			
			#~ Create the ECQ
			ruleCond = ECQ(rule["ruleCondition"][0], self.__concepts, self.__roles, self.__individuals)
			
			#~ We need to check that the terms used in the rules are present in the
			#~ TBox vocabulary (thus, in the predicate section)
			if not ruleCond.concepts().issubset(self.__concepts):
				raise Exception("The following rule is using terms that are not concepts in the predicates: (:" + str(rule["ruleName"]) + " ... )\n" \
				"Terms that are not concepts: " + str(ruleCond.concepts().difference(self.__concepts)))
			if not ruleCond.roles().issubset(self.__roles):
				raise Exception("The following rule is using terms that are not roles in the predicates: (:" + str(rule["ruleName"]) + " ... )\n" \
				"Terms that are not roles: " + str(ruleCond.roles().difference(self.__roles)))
			
			#~ Check that the action called exists
			found = False
			for action in result["actions"]:
				if str(rule["ruleAction"]) == str(action["actionName"]):
					found = True
			
			if not found:
				raise Exception("The rule (:" + str(rule["ruleName"]) + " ... ) is calling an action ("+ str(rule["ruleAction"]) + " ... ) that is not specified after.")
				
			#~ Save the rule
			self.__rules.add((str(rule["ruleName"]), ruleCond, str(rule["ruleAction"])))
		
		#~ 
		#~ Analyse the actions
		#~ 
		for action in result["actions"]:
			
			#~ Check that no other action has the same name
			for otherAction in result["actions"]:
				if action != otherAction and str(action["actionName"]) == str(otherAction["actionName"]):
					raise Exception("There are two actions with the same name: " + str(action["actionName"]))
			
			#~ Save the parameters in a tuple
			actionParameters = tuple([Variable(parameter) for parameter in action["actionParameters"]])
			
			#~ Every action can be called only by one rule, and
			#~ the free variables of the rule condition must be a subset of
			#~ the parameters of the action.
			counter = 0
			for rule in self.__rules:
				if str(action["actionName"]) == rule[2]:
					#~ Increase the counter
					counter += 1
					
					#~ Check the free variables
					if not rule[1].freeVars().issubset(actionParameters):
						raise Exception("The rule " + rule[0] + " calls the action " + str(action["actionName"]) + \
						", but the free variables of its condition (" + str(rule[1].freeVars()) + \
						") are not a subset of the parameters of the action (" + str(actionParameters) + ").")
			
			#~ Check that only one rule calls the action
			if counter != 1:
				raise Exception("There are " + str(counter) + " rules that call the action " + str(action["actionName"]) +". There must be 1!")
			
			#~ Analyze each effect
			effects = [] # Temporary list for the effects
			for effect in action["actionEffects"]:
				
				#~ Create the ECQ of the effect
				effectCond = ECQ(effect["effectCondition"][0], self.__concepts, self.__roles, self.__individuals)
				
				#~ We need to check that the terms used in the effect condition are present in the
				#~ TBox vocabulary (thus, in the predicate section)
				if not effectCond.concepts().issubset(self.__concepts):
					raise Exception("The following action is using terms that are not concepts in the predicates: (:" + str(action["actionName"]) + " ... )\n" \
					"Terms that are not concepts: " + str(effectCond.concepts().difference(self.__concepts)))
				if not effectCond.roles().issubset(self.__roles):
					raise Exception("The following action is using terms that are not roles in the predicates: (:" + str(action["actionName"]) + " ... )\n" \
					"Terms that are not roles: " + str(effectCond.roles().difference(self.__roles)))
				
				effectConcepts = set() #Set used to save the concepts that appear in the effects, for check purposes
				effectRoles = set() #Set used to save the roles that appear in the effects, for check purposes
				effectVars = set() #Set used to save the variables that appear in the effects, for check purposes
				
				effectAdd = [] # Temporary list for the addition effects
				if "effectAdd" in effect.keys():
					for atomicEffect in effect["effectAdd"][0]:
						
						atom = QueryAtom(atomicEffect, self.__concepts, self.__roles, self.__individuals)
						
						if atom.atomType() == "role":
							effectRoles.add(atom.term())
							
							if isinstance(atom.var1(), Variable):
								effectVars.add(atom.var1())
							if isinstance(atom.var2(), Variable):
								effectVars.add(atom.var2())
						elif atom.atomType() == "concept":
							effectConcepts.add(atom.term())
							
							if isinstance(atom.var1(), Variable):
								effectVars.add(atom.var1())
						else:
							raise Exception("An atomic effect can be only about a concept or a role. The following atom is not valid: " + str(atom))
								
						effectAdd.append(atom) # Add the effect to the list
				
				effectDel = [] # Temporary list for the deletion effects
				if "effectDelete" in effect.keys():
					for atomicEffect in effect["effectDelete"][0]:
						
						atom = QueryAtom(atomicEffect, self.__concepts, self.__roles, self.__individuals)
						
						if atom.atomType() == "role":
							effectRoles.add(atom.term())
							
							if isinstance(atom.var1(), Variable):
								effectVars.add(atom.var1())
							if isinstance(atom.var2(), Variable):
								effectVars.add(atom.var2())
						elif atom.atomType() == "concept":
							effectConcepts.add(atom.term())
							
							if isinstance(atom.var1(), Variable):
								effectVars.add(atom.var1())
						else:
							raise Exception("An atomic effect can be only about a concept or a role. The following atom is not valid: " + str(atom))
						
						effectDel.append(atom) # Add the effect to the list
				
				#~ We need to check that the terms used in the atomic effects are present in the
				#~ TBox vocabulary (thus, in the predicate section)
				if not effectConcepts.issubset(self.__concepts):
					raise Exception("The following action is using terms that are not concepts in the predicates: (:" + str(action["actionName"]) + " ... )\n" \
					"Terms that are not concepts: " + str(effectConcepts.difference(self.__concepts)))
				if not effectRoles.issubset(self.__roles):
					raise Exception("The following action is using terms that are not roles in the predicates: (:" + str(action["actionName"]) + " ... )\n" \
					"Terms that are not roles: " + str(effectRoles.difference(self.__roles)))
				
				#~ We need to check that the variables used in the atomic effects are present either 
				#~ in the ECQ of the effect, or in the parameters of the action.
				if not effectVars.issubset(effectCond.freeVars().union(actionParameters)):
					raise Exception("The following action is using variables in the atomic effects that do not appear among the free variables of the effect's condition: (:" + str(action["actionName"]) + " ... )\n" \
					"Variables that do not appear in the condition: " + str(effectVars.difference(effectCond.freeVars())))
				
				#~ Save the analyzed effect as a tuple
				effects.append(tuple((effectCond,tuple(effectAdd),tuple(effectDel))))
			
			#~ Save the action
			self.__actions.add( tuple((str(action["actionName"]),actionParameters,tuple(effects))) )
Пример #16
0
    def __rewriteUCQ(query, posAxioms):

        if not isinstance(query, UCQ):
            raise Exception(
                "The function __rewriteUCQ can work only with objects of the class UCQ(). It was instead passed a "
                + str(type(query)))

        #~ Algorithm PerfectRef(q, T)
        #~ Input: UCQ q, DL-LiteA TBox T
        #~ Output: UCQ pr
        #~
        #~ pr := q;
        #~ repeat
        #~ pr' := pr;
        #~ for each CQ q' ∈ pr' do
        #~ for each atom g in q' do
        #~ for each PI α in T do
        #~ if α is applicable to g then
        #~ pr := pr ∪{q?[g/gr(g,α)] };
        #~
        #~ for each pair of atoms g1,g2 in q? do
        #~ if g1 and g2 unify then
        #~ pr := pr ∪ {anon(reduce(q?,g1,g2))};
        #~ until pr' = pr;
        #~ return pr

        syntax = Syntax()

        #~ Implement the line:
        #~ pr := q;
        rewrittenUCQ = set(query.cqs())
        #~ for cq in query.cqs():
        #~ rewrittenUCQ.add(cq)

        #~ Implement the line:
        #~ repeat
        while True:

            #~ Implement the line:
            #~ pr' := pr;
            rewrittenUCQold = set(rewrittenUCQ)
            #~ for cq in rewrittenUCQ:
            #~ rewrittenUCQold.add(cq)

            #~ Implement the line:
            #~ for each CQ q' ∈ pr' do
            for cq in rewrittenUCQold:

                #~ Implement the line:
                #~ for each atom g in q' do
                #~ for each PI α in T do
                for (atom, axiom) in itertools.product(cq.queryAtoms(),
                                                       posAxioms):

                    #~ print("Checking axiom: " + str(axiom))

                    #~ Implement the line:
                    #~ if α is applicable to g then
                    #~ pr := pr ∪{q'[g/gr(g,α)] };
                    newAtom = __applyAxiom(atom, axiom)

                    if not newAtom is None:
                        #~ Calculate q'[g/gr(g,α)]
                        newAtoms = [
                        ]  # The atoms that compose the rewritten cq
                        for atomTemp in cq.queryAtoms(
                        ):  # We copy all the query atoms, and just substitute the rewritten one
                            if atomTemp == atom:  # We check if it is the atom that was rewritten
                                newAtoms.append(
                                    newAtom)  # We add the rewritten atom
                            else:
                                newAtoms.append(atomTemp)

                        logger.info("for axiom in posAxioms:")
                        logger.info(str(cq))
                        logger.info(str(cq.queryAtoms()))
                        logger.info(str(atom))
                        logger.info(str(axiom))
                        logger.info(str(newAtom))
                        logger.info(str(newAtoms))
                        logger.info(" ")

                        #~ If the __applyAxiom function added a NDNSVariable() to newAtom,
                        #~ then we have to add it to the existential variables of the rewritten CQ
                        ndnsVar = NDNSVariable()
                        if ndnsVar in newAtom.freeVars():
                            newExistentialVars = set([ndnsVar])
                            if len(cq.existentialVars()) > 0:
                                newExistentialVars.update(cq.existentialVars())

                            rewrittenUCQ.add(
                                CQ(
                                    {
                                        "queryAtoms": newAtoms,
                                        "existentialVars": newExistentialVars
                                    }, conceptList, roleList, individualList))

                        else:

                            #~ Calculate the new existential vars set, because it could be the case that we
                            #~ substitute a role with a concept, in which case we may reduce the number of
                            #~ existential vars.
                            #~ Example:
                            #~ - we start with (exists ( ?_ ?x_1 ) (and (hasPersonalInfo ?x_1 ?_) (FullName ?x_1) ) )
                            #~ - we apply the axiom (isA Employee (exists hasPersonalInfo))
                            #~ - we substitute (hasPersonalInfo ?x_1 ?_) with (Employee ?x_1)
                            #~ - ?_ is not an existential var anymore
                            newExistentialVars = set()
                            for var in cq.existentialVars():
                                for atom in newAtoms:
                                    if var in atom.freeVars():
                                        newExistentialVars.add(var)

                            rewrittenUCQ.add(
                                CQ(
                                    {
                                        "queryAtoms": newAtoms,
                                        "existentialVars": newExistentialVars
                                    }, conceptList, roleList, individualList))

                #~ Implement the line: for each pair of atoms g1,g2 in q' do
                for (atom1,
                     atom2) in itertools.combinations(cq.queryAtoms(), 2):

                    #~ Implement the line:
                    #~ if g1 and g2 unify then
                    #~ pr := pr ∪{anon(reduce(q',g1,g2))};
                    newCQ = __anon(__reduce(cq, atom1, atom2), cq.freeVars())

                    #~ print("Old CQ: " + str(cq))
                    #~ print("New CQ: " + str(newCQ))

                    if not newCQ is None:
                        rewrittenUCQ.add(newCQ)

            logger.info("rewrittenUCQ:")
            logger.info(rewrittenUCQ)
            logger.info(" ")

            #~ Implement the line:
            #~ until pr' = pr;
            if rewrittenUCQold == rewrittenUCQ:
                break

        #~ We have to substitutes each instance of NDNSVariable()
        #~ with a proper variable Variable().
        #~ NDNSVariable() instances can appear only in the CQs which
        #~ have existential variables.
        rewrittenUCQ_wo_NDNSVariables = set()
        for cq in rewrittenUCQ:
            if any([
                    isinstance(var, NDNSVariable)
                    for var in cq.existentialVars()
            ]):

                cq_wo_NDNSVariables_existentialVars = set(
                )  # Temporary set in which the vars that substitute the NDNSVariable are saved
                cq_wo_NDNSVariables = set(
                )  # Temporary set in which we save the query atoms that contain the changed NDNSVariables
                counter = 0  # Used to generate uniquely named variables

                #~ Check if among the query atoms the NDNSVariable is used
                for queryAtom in cq.queryAtoms():

                    newVar1 = None
                    newVar2 = None

                    if isinstance(queryAtom.var1(), NDNSVariable):
                        #~ We need to change it.

                        #~ Create a uniquely named variable
                        newVar1 = Variable(syntax.ndnsVariable + str(counter))
                        #~ Increase the counter
                        counter += 1

                        #~ Save the new variable in the set substituteVars
                        cq_wo_NDNSVariables_existentialVars.add(newVar1)
                    else:
                        newVar1 = queryAtom.var1()

                    if isinstance(queryAtom.var2(), NDNSVariable):
                        #~ We need to change it.

                        #~ Create a uniquely named variable
                        newVar2 = Variable(syntax.ndnsVariable + str(counter))
                        #~ Increase the counter
                        counter += 1

                        #~ Save the new variable in the set substituteVars
                        cq_wo_NDNSVariables_existentialVars.add(newVar2)

                    else:
                        newVar2 = queryAtom.var2()

                    #~ Create a new queryAtom where the NDNSVariable is
                    #~ changed with the new one, and save it in cqs_wo_NDNSVariables.
                    if newVar2 is None:
                        cq_wo_NDNSVariables.add(
                            QueryAtom([queryAtom.term(), newVar1], conceptList,
                                      roleList, individualList))
                    else:
                        cq_wo_NDNSVariables.add(
                            QueryAtom([queryAtom.term(), newVar1, newVar2],
                                      conceptList, roleList, individualList))

                #~ Update cq_wo_NDNSVariables_existentialVars by adding other
                #~ existential vars, but not NDNSVariable.
                for var in cq.existentialVars():
                    if not isinstance(var, NDNSVariable):
                        cq_wo_NDNSVariables_existentialVars.add(var)

                #~ Save the cq in rewrittenUCQ_wo_NDNSVariables
                rewrittenUCQ_wo_NDNSVariables.add(
                    CQ(
                        {
                            "queryAtoms": cq_wo_NDNSVariables,
                            "existentialVars":
                            cq_wo_NDNSVariables_existentialVars
                        }, conceptList, roleList, individualList))

            else:
                #~ The cq doesn't use any NDNSVariable. We copy it in rewrittenUCQ_wo_NDNSVariables
                rewrittenUCQ_wo_NDNSVariables.add(cq)

        #~ Implement the line:
        #~ return pr
        rewrittenUCQ = list(rewrittenUCQ_wo_NDNSVariables)
        if len(rewrittenUCQ) > 1:
            rewrittenUCQ.insert(0, syntax.queryOr)

        #~ print("Fine __rewriteUCQ")
        #~ print(str(list(rewrittenUCQ)))
        #~ print("---------------------------\n")

        return rewrittenUCQ
Пример #17
0
    def toADL(self, domainOutputFilePath, problemOutputFilePath):
        """The function toADL translates an input eKab to a PDDL-ADL
		planning problem."""

        #~ An ADL planning problem written in PDDL is composed by two parts,
        #~ the domain file and the problem file.
        #~ We start by creating the domain file, which contains the following sections:
        #~ (domain domain name)
        #~ (:requirements :adl)
        #~ (:predicates predicates list)
        #~ (:action action name
        #~ :parameters ( parameters )
        #~ :precondition precondition Query
        #~ :effect effects
        #~ )
        #~ ... more actions
        #~
        #~ An ADL action is the merge of an eKab condition/action rule with
        #~ the related called action.
        #~ An ADL action is formed as follow:
        #~ (:action action name
        #~ :parameters ( parameters )
        #~ :precondition precondition Query
        #~ :effect effects
        #~ )
        #~ where:
        #~ - parameters are the parameters of the eKab action
        #~ - the precondition query is the rule's condition, to which we
        #~   add the negated boolean predicates CheckConsistency and Error
        #~ - the effect of the action is the conjunction of the effects of
        #~   the eKab action, plus the boolean predicate CheckConsistency
        #~
        #~ The problem file contains the following sections:
        #~ (define (problem problem name)
        #~ (:domain domain name)
        #~ (:objects individuals list)
        #~ (:init membership assertions list + (not (CheckConsistency)) + (not (Error)) )
        #~ (:goal
        #~ rewritten goal query
        #~ )

        syntax = Syntax()

        indentLevel = 1

        #~ Check if domainOutputFilePath is a proper file path
        if not isinstance(domainOutputFilePath, str):
            raise Exception(
                "The file path for the planning domain must be a string! Type provided: "
                + str(type(domainOutputFilePath)))
        if domainOutputFilePath[-5:] != ".pddl":
            raise Exception(
                "The file for the planning domain must have a .pddl extension!"
            )

        #~ Check if domainOutputFilePath is already a file.
        #~ If yes, ask for permission to overwrite it.
        if os.path.isfile(domainOutputFilePath):

            while True:
                print("The specified file (" + domainOutputFilePath +
                      ") already exists. Overwrite it?")
                answer = input("Y/n: ")

                if answer == "Y" or answer == "y":
                    break
                elif answer == "N" or answer == "n":
                    print("OK. The translation to ADL will halt here.")
                    return 0
                else:
                    print(
                        "Answer not recognized. Please type either \"Y\" or \"n\"."
                    )

        #~ Check if problemOutputFilePath is a proper file path
        if not isinstance(problemOutputFilePath, str):
            raise Exception(
                "The file path for the planning problem must be a string! Type provided: "
                + str(type(problemOutputFilePath)))
        if problemOutputFilePath[-5:] != ".pddl":
            raise Exception(
                "The file for the planning problem must have a .pddl extension!"
            )

        #~ Check if problemOutputFilePath is already a file.
        #~ If yes, ask for permission to overwrite it.
        if os.path.isfile(problemOutputFilePath):

            while True:
                print("The specified file (" + problemOutputFilePath +
                      ") already exists. Overwrite it?")
                answer = input("Y/n: ")

                if answer == "Y" or answer == "y":
                    break
                elif answer == "N" or answer == "n":
                    print("OK. The translation to ADL will halt here.")
                    return 0
                else:
                    print(
                        "Answer not recognized. Please type either \"Y\" or \"n\"."
                    )

        #~ Open the file for the domain
        domainOutputFile = open(domainOutputFilePath, "wt")

        #~ Write "(define"
        domainOutputFile.write("(define\n")
        #~ Write the domain name
        domainOutputFile.write(
            indent(indentLevel) + "(domain " + self.__ekab.domainName() +
            ")\n")
        #~ Write "(:requirements :adl)"
        domainOutputFile.write(indent(indentLevel) + "(:requirements :adl)\n")
        #~ Write the predicates list
        domainOutputFile.write(indent(indentLevel) + "(:predicates\n")
        indentLevel += 1
        for concept in self.__ekab.concepts():
            domainOutputFile.write(
                indent(indentLevel) + "(" + str(concept) + " ?x )\n")
        for role in self.__ekab.roles():
            domainOutputFile.write(
                indent(indentLevel) + "(" + str(role) + " ?x ?y )\n")

        #~ Add the boolean predicates CheckConsistency and Error
        domainOutputFile.write(
            indent(indentLevel) + "(" + syntax.ADLCheckConsistency + ")\n")
        domainOutputFile.write(
            indent(indentLevel) + "(" + syntax.ADLError + ")\n")

        #~ Close the :predicates section
        indentLevel -= 1
        domainOutputFile.write(indent(indentLevel) + ")\n")

        #~ Write the actions
        #~ We use the rewritten actions
        for action in self.__ekab.actionsRewritten():

            #~ Find the related rewritten rule
            relatedRule = None
            for rule in self.__ekab.rulesRewritten():
                if rule[2] == action[0]:
                    relatedRule = rule
                    break

            if relatedRule is None:
                #~ The action has no related rule, and this can't be
                raise Exception("The action " + action[0] +
                                " has no related rule, and this can't be.")

            #~ Write the action name
            domainOutputFile.write(
                indent(indentLevel) + "(:action " + action[0] + "\n")
            indentLevel += 1

            #~ Write the action's parameters.
            #~ parameters are the parameters of the eKab action
            domainOutputFile.write(indent(indentLevel) + ":parameters ( ")
            for param in action[1]:
                domainOutputFile.write(str(param) + " ")
            domainOutputFile.write(")\n")

            #~ Write the action's precondition.
            #~ The precondition query is the rule's condition, to which we
            #~ add the negated boolean predicates CheckConsistency and Error
            domainOutputFile.write(
                indent(indentLevel) + ":precondition ( and\n")
            domainOutputFile.write(
                indent(indentLevel + 1) + "(not (" +
                syntax.ADLCheckConsistency + "))\n")
            domainOutputFile.write(
                indent(indentLevel + 1) + "(not (" + syntax.ADLError + "))\n")
            domainOutputFile.write(relatedRule[1].toADL(indentLevel + 1))
            domainOutputFile.write(indent(indentLevel) +
                                   ")\n")  # Close the precondition

            #~ Write the effects of the action
            domainOutputFile.write(indent(indentLevel) + ":effect ( and\n")
            indentLevel += 1
            domainOutputFile.write(
                indent(indentLevel) + "(" + syntax.ADLCheckConsistency + ")\n")
            #~ For each effect in the eKab action, we create a conditional ADL effect
            for effect in action[2]:
                domainOutputFile.write(
                    indent(indentLevel) + "(when\n" +
                    effect[0].toADL(indentLevel + 1))

                domainOutputFile.write(indent(indentLevel + 1) + "(and\n")
                #~ Add the add effects
                for addEff in effect[1]:
                    domainOutputFile.write(addEff.toADL(indentLevel + 2))
                #~ Add the del effects
                for delEff in effect[2]:
                    domainOutputFile.write(
                        indent(indentLevel + 2) + "(not " +
                        delEff.toADL(0)[:-1] + ")\n")
                #~ domainOutputFile.write(indent(indentLevel+2) + ")\n") # Close not
                domainOutputFile.write(indent(indentLevel + 1) +
                                       ")\n")  # Close and

                domainOutputFile.write(indent(indentLevel) +
                                       ")\n")  # Close when

            indentLevel -= 1
            domainOutputFile.write(indent(indentLevel) +
                                   ")\n")  # Close the effect

            indentLevel -= 1
            domainOutputFile.write(indent(indentLevel) +
                                   ")\n")  # Close the action

        #~ Add the special action to check consistency
        domainOutputFile.write(
            indent(indentLevel) + "(:action " +
            syntax.ADLCheckConsistencyAction + "\n")
        indentLevel += 1

        #~ The action has no parameters, since queryUnsatRewritten is a boolean query
        domainOutputFile.write(indent(indentLevel) + ":parameters ( )\n")

        #~ Write the action's precondition.
        #~ The precondition query is conjunction of
        #~ the boolean predicate CheckConsistency and the negated Error
        domainOutputFile.write(indent(indentLevel) + ":precondition ( and\n")
        domainOutputFile.write(
            indent(indentLevel + 1) + "(" + syntax.ADLCheckConsistency + ")\n")
        domainOutputFile.write(
            indent(indentLevel + 1) + "(not (" + syntax.ADLError + "))\n")
        domainOutputFile.write(indent(indentLevel) +
                               ")\n")  # Close the precondition

        #~ Write the effects of the action, which are two:
        #~ - one has as precondition queryUnsatRewritten, and, if Ture, set Error to True
        #~ - the other simply set to False CheckConsistency
        domainOutputFile.write(indent(indentLevel) + ":effect ( and\n")
        indentLevel += 1
        domainOutputFile.write(
            indent(indentLevel) + "(not (" + syntax.ADLCheckConsistency +
            "))\n")
        domainOutputFile.write(
            indent(indentLevel) + "(when\n" +
            self.__ekab.queryUnsatRewritten().toADL(indentLevel + 1))
        domainOutputFile.write(
            indent(indentLevel + 1) + "(" + syntax.ADLError + ")\n")
        domainOutputFile.write(indent(indentLevel) + ")\n")  # Close when
        indentLevel -= 1
        domainOutputFile.write(indent(indentLevel) + ")\n")  # Close the effect

        indentLevel -= 1
        domainOutputFile.write(indent(indentLevel) + ")\n")  # Close the action

        domainOutputFile.write(")")  # Close define

        #~ Close the file
        domainOutputFile.close()

        #~ -----------------------------------------------------------

        #~ Open the file for the domain
        problemOutputFile = open(problemOutputFilePath, "wt")

        #~ Write "(define (problem problem name)"
        problemOutputFile.write("(define (problem " +
                                self.__ekab.problemName() + " )\n")
        #~ Write the domain name
        problemOutputFile.write(
            indent(indentLevel) + "(:domain " + self.__ekab.domainName() +
            ")\n")
        #~ Write the individuals list
        problemOutputFile.write(
            indent(indentLevel) + "(:objects\n" + indent(indentLevel + 1))
        for individual in self.__ekab.individuals():
            problemOutputFile.write(str(individual) + " ")
        problemOutputFile.write("\n" + indent(indentLevel) +
                                ")\n")  # Close :objects

        #~ Write the membership assertions list
        problemOutputFile.write(indent(indentLevel) + "(:init\n")
        for assertion in self.__ekab.assertions():
            problemOutputFile.write(assertion.toADL(indentLevel + 1))
        #~ Add (not (CheckConsistency)) and (not (Error))
        problemOutputFile.write(
            indent(indentLevel + 1) + "(not (" + syntax.ADLCheckConsistency +
            "))\n")
        problemOutputFile.write(
            indent(indentLevel + 1) + "(not (" + syntax.ADLError + "))\n")

        problemOutputFile.write(indent(indentLevel) + ")\n")  # Close :init

        #~ Write the goal
        problemOutputFile.write(indent(indentLevel) + "(:goal\n")
        problemOutputFile.write(indent(indentLevel + 1) + "(and\n")
        problemOutputFile.write(
            indent(indentLevel + 2) + "(not (" + syntax.ADLCheckConsistency +
            "))\n")
        problemOutputFile.write(
            indent(indentLevel + 2) + "(not (" + syntax.ADLError + "))\n")

        #~ Check if the goal query is a conjunction of ECQs or a CQ.
        #~ If this is the case, then we need to remove the additional "(and ..." in which
        #~ the translated query in ADL will come with, as we already have added one.
        #~ Failing to do so, will raise an error in FastDownward:
        #~ AssertionError: Condition not normalized: ...
        if len(self.__ekab.goalQueryRewritten().ecqs()) > 1:
            #~ It is a conjunction of ECQs
            #~ We add the single inner ECQs translated to ADL
            for ecq in self.__ekab.goalQueryRewritten().ecqs():
                problemOutputFile.write(ecq.toADL(indentLevel + 2))

        elif self.__ekab.goalQueryRewritten().ucq() is not None and \
         len(self.__ekab.goalQueryRewritten().ucq().cqs()) == 1:

            #~ We have a single CQ
            for cq in self.__ekab.goalQueryRewritten().ucq().cqs():
                if len(cq.existentialVars()) == 0 and len(cq.queryAtoms()) > 1:
                    #~ It is a single CQ with no existential vars and more than one atom
                    for atom in cq.queryAtoms():
                        problemOutputFile.write(atom.toADL(indentLevel + 2))
                else:
                    problemOutputFile.write(cq.toADL(indentLevel + 2))
        else:
            problemOutputFile.write(
                self.__ekab.goalQueryRewritten().toADL(indentLevel + 2))

        problemOutputFile.write(indent(indentLevel + 1) + ")\n")  # Close and
        problemOutputFile.write(indent(indentLevel) + ")\n")  # Close :goal

        problemOutputFile.write(")")  # Close define

        #~ Close the file
        problemOutputFile.close()
Пример #18
0
 def findAllReferences(self, var, indexrange, left_propa):
     visited=set()
     pairs=set()
     if indexrange==[]:return []
     indexrange.sort()
     V=set([(indexrange[0],var,left_propa,0,len(indexrange))])
     if left_propa:
         for temp_lb in range(0,len(indexrange)):
             temp_index=indexrange[temp_lb]
             print var.pointerStr()
             print temp_index,self.l[temp_index]
             m=re.search(r'(?<![A-Za-z0-9_])'+var.pointerStr()+r"\s*=(?!=)",self.l[temp_index].codestr)
             if m:
                 result=Syntax.isPossibleArgumentDefinition(self.l[temp_index],var)
                 leftpart=m.group()[:-1].strip()
                 rfl,pat=var.matchAccessPattern(leftpart)
                 if rfl>0 or result is not None:
                     lb=temp_lb+1
                 else:
                     lb=temp_lb
                 V=set([(indexrange[0],var,left_propa,0,lb)])
                 break
     count=0
     while len(V)>0:
         A=set()
         for index,v,left_p,upperbound,lowerbound in V:
             #if not v.pointerStr():continue
             #lp=Syntax.left_ref_propagate_pattern(v)
             rp=Syntax.right_ref_propagate_pattern(v)
             print "Continue Check bellow the first found assignment:",self.l[index]
             for idx in range(upperbound,lowerbound):
                 aIndex=indexrange[idx]
                 if left_p and aIndex<index:
                     print "pass(accelerate)",v.simple_access_str()
                 elif aIndex in visited:
                     print "pass(accelerate)",v.simple_access_str()
                 elif re.search(r"[^=]=[^=]",self.l[aIndex].codestr) is None:
                     print "pass",v.simple_access_str()
                     visited.add(aIndex) 
                 else:
                     print "Line Under Check:",self.l[aIndex]
                     if "&hdr;" in self.l[aIndex].codestr:
                             print "Find IT!"
                     match=self.isLeftPropagate(v,self.l[aIndex].codestr)
                     if match is not None:
                         m_left_propgate=match
                         print "find left propagate:",self.l[aIndex]
                         array=m_left_propgate.group().split("=")
                         leftpart=array[0].split()[-1].lstrip("*")
                         rightpart=array[1].strip()
                         rightvar=rightpart.rstrip(";").strip()
                         if rightvar[0]=="(":
                             stack=[]
                             i=1
                             while i<len(rightvar):
                                 if rightvar[i]=="(":
                                     stack.append("(")
                                 elif rightvar[i]==")":
                                     if len(stack)>0:
                                         stack.pop()
                                     else:
                                         rightvar=rightvar[i+1:].strip().lstrip("(").rstrip(")").strip()
                                         break
                                 i+=1
                         rfl,pat=v.matchAccessPattern(rightvar)
                         if "*"==pat[-1] or "->" in pat[-1] and aIndex>index:
                             if rfl<=0:rfl=1
                         q=TaintVar(leftpart,pat,rfl,True)#Note that we should take ref_len in to consideration.
                         lb=lowerbound
                         if idx+1<lowerbound:
                             for temp_lb in range(idx+1,lowerbound):
                                 temp_index=indexrange[temp_lb]
                                 print v.pointerStr()
                                 print q.pointerStr()
                                 print temp_index,self.l[temp_index]
                                 if re.search(q.pointerStr()+r"\s*[^=]=[^=]",self.l[temp_index].codestr):
                                     result=Syntax.isPossibleArgumentDefinition(self.l[temp_index],q)
                                     if result is not None:
                                         lb=temp_lb+1
                                     else:
                                         lb=temp_lb
                                     break     
                         pairs.add((aIndex,q,True,idx+1,lb))
                         A.add((aIndex,q,True,idx+1,lb))
                         visited.add(aIndex)
                     elif rp:
                         print rp
                         m_right_propgate=re.search(rp,self.l[aIndex].codestr)
                         if m_right_propgate:
                             array=m_right_propgate.group().split("=")
                             leftpart=array[0].strip()
                             rightpart=array[1].strip()
                             rightvar=rightpart.rstrip(";").strip()
                             rfl,pat=v.matchAccessPattern(leftpart)
                             # BUG if look downward
                             if rfl==0:
                                 print "HEY"
                             if left_p and rfl>0:#v is KILLED here! Skip the following index range, and inform other left propagation
                                 lowerbound=indexrange.index(aIndex)
                                 #Stop find other references
                                 #Because it's killed here. LOWER statements that use it is meaningless
                                 break
                             if "*"==pat[-1] or "->" in pat[-1] and aIndex>=index:
                                 if rfl<=0:rfl=1
                             q=TaintVar(rightvar,pat,rfl,True)#Note that we should take ref_len in to consideration.
                             print aIndex,self.l[aIndex]
                             print q
                             print v
                             pairs.add((aIndex,q,False,upperbound,lowerbound))
                             A.add((aIndex,q,False,upperbound,lowerbound))
                             visited.add(aIndex)
         count+=1
         V=A
     pairs=list(pairs)
     print "refrences list-------"
     for pair in pairs:
         print pair[0],pair[1],pair[2],pair[3],pair[4]
     pairs.sort(lambda x,y:cmp(x[0],y[0]))
     return pairs
Пример #19
0
    def __rewriteECQ(query, posAxioms):
        #~ Possible ECQs:
        #~ - True
        #~ - ["not", ECQ]
        #~ - ["exists", [vars], ECQ]
        #~ - ["and", ECQ, ... , ECQ]
        #~ - ["mko-eq", var1, var2]
        #~ - ["mko", UCQ]

        if not isinstance(query, ECQ):
            raise Exception(
                "The function __rewriteECQ can work only with objects of the class ECQ(). It was instead passed a "
                + str(type(query)))

        syntax = Syntax()

        if query.isTrue():
            #~ Return the keyword True
            return [syntax.true]

        elif query.isNegated():
            #~ ["not", ECQ]
            if len(query.ecqs()) != 1:
                raise Exception(
                    "Something is wrong. A negated ECQ (\"(not ECQ)\") can contain only one internal ECQ, while here there are "
                    + len(query.ecqs()) + ".")

            for ecq in query.ecqs():
                return [syntax.neg, __rewriteECQ(ecq, posAxioms)]

        elif len(query.existentialVars()) > 0:
            #~ ["exists", [vars], ECQ]

            if len(query.ecqs()) != 1:
                raise Exception(
                    "Something is wrong. An existential ECQ (\"(exists (vars) ECQ)\") can contain only a list of existential variables, and one internal ECQ"
                )

            for ecq in query.ecqs():
                return [
                    syntax.exists,
                    [str(var) for var in query.existentialVars()],
                    __rewriteECQ(ecq, posAxioms)
                ]

        elif len(query.ecqs()) > 0:
            #~ ["and", ECQ, ... , ECQ]
            rewrittenEcq = [syntax.queryAnd]

            for ecq in query.ecqs():
                rewrittenEcq.append(__rewriteECQ(ecq, posAxioms))

            return rewrittenEcq

        elif isinstance(query.equalityVar1(), Variable) and isinstance(
                query.equalityVar2(), Variable):
            #~ ["mko-eq", var1, var2]

            eqEcq = [
                syntax.mkoEq,
                str(query.equalityVar1()),
                str(query.equalityVar2())
            ]

            return eqEcq

        elif not query.ucq() is None:
            #~ ["mko", UCQ]
            return [syntax.mko, __rewriteUCQ(query.ucq(), posAxioms)]

        else:
            #~ If I reach this point, something went wrong
            raise Exception(
                "Something went wrong in the query rewriting of the query:\n" +
                str(self))
Пример #20
0
    def __applyAxiom(queryAtom, axiom):
        """
		The function checks if, given a query atom and axiom,
		we can apply the axiom and thus genereate a new "rewritten" query atom.
		We follow the table reported in Fig. 12 of [Calvanese2009].
		The table is:
		
		Atom g	| Axiom alpha					| gr(g, alpha)
		--------|-------------------------------|----------------
		A(x)	| A1 isA A						| A1(x)
		A(x)	| exists P isA A				| P(x,_)
		A(x)	| exists P^- isA A				| P(_,x)
		P(x,_)	| A isA exists P				| A(x)
		P(x,_)	| exists P1 isA exists P		| P1(x,_)
		P(x,_)	| exists P1^- isA exists P		| P1(_,x)
		P(_,y)	| A isA exists P^-				| A(y)
		P(_,y)	| exists P1 isA exists P^-		| P1(y,_)
		P(_,y)	| exists P1^- isA exists P^-	| P1(_,y)
		P(x,y)	| P1 isA P , P1^- isA P^-		| P1(x,y)
		P(x,y)	| P1 isA P^- , P1^- isA P		| P1(y,x)
		"""

        syntax = Syntax()

        #~ Check if the axiom involves, in the right side, the term used in the atom
        if queryAtom.term() == axiom.rightTerm():

            if not axiom.leftTermExists() and \
             not axiom.leftTermInverse() and \
             not axiom.rightTermExists() and \
             not axiom.rightTermInverse() and \
             not isinstance(queryAtom.var1(), NDNSVariable):
                #~ We have one of the following situations:
                #~ A1 isA A
                #~ P1 isA P

                if queryAtom.var2() is None:
                    #~ Return A1(x)
                    return QueryAtom(
                        [axiom.leftTerm(), queryAtom.var1()], conceptList,
                        roleList, individualList)
                elif isinstance(queryAtom.var2(), Variable):
                    #~ Return P1(x,y)
                    return QueryAtom(
                        [axiom.leftTerm(),
                         queryAtom.var1(),
                         queryAtom.var2()], conceptList, roleList,
                        individualList)

            elif axiom.leftTermExists() and \
             not axiom.leftTermInverse() and \
             not axiom.rightTermExists() and \
             not axiom.rightTermInverse() and \
             not isinstance(queryAtom.var1(), NDNSVariable):
                #~ We have the following situations:
                #~ exists P isA A
                #~ Return P(x,_)
                return QueryAtom(
                    [axiom.leftTerm(),
                     queryAtom.var1(),
                     NDNSVariable()], conceptList, roleList, individualList)

            elif axiom.leftTermExists() and \
             axiom.leftTermInverse() and \
             not axiom.rightTermExists() and \
             not axiom.rightTermInverse() and \
             not isinstance(queryAtom.var1(), NDNSVariable):
                #~ We have the following situations:
                #~ exists P^- isA A
                #~ Return P(_,x)
                return QueryAtom(
                    [axiom.leftTerm(),
                     NDNSVariable(),
                     queryAtom.var1()], conceptList, roleList, individualList)

            elif not axiom.leftTermExists() and \
             not axiom.leftTermInverse() and \
             axiom.rightTermExists() and \
             not axiom.rightTermInverse() and \
             not isinstance(queryAtom.var1(), NDNSVariable) and \
             isinstance(queryAtom.var2(), NDNSVariable):
                #~ We have the following situations:
                #~ A isA exists P
                #~ Return A(x)
                return QueryAtom(
                    [axiom.leftTerm(), queryAtom.var1()], conceptList,
                    roleList, individualList)

            elif not axiom.leftTermExists() and \
             not axiom.leftTermInverse() and \
             axiom.rightTermExists() and \
             axiom.rightTermInverse() and \
             not isinstance(queryAtom.var2(), NDNSVariable) and \
             isinstance(queryAtom.var1(), NDNSVariable):
                #~ We have the following situations:
                #~ A isA exists P^-
                #~ Return A(y)
                return QueryAtom(
                    [axiom.leftTerm(), queryAtom.var2()], conceptList,
                    roleList, individualList)

            elif axiom.leftTermExists() and \
             not axiom.leftTermInverse() and \
             axiom.rightTermExists() and \
             not axiom.rightTermInverse() and \
             not isinstance(queryAtom.var1(), NDNSVariable) and \
             isinstance(queryAtom.var2(), NDNSVariable):
                #~ We have the following situations:
                #~ exists P1 isA exists P
                #~ Return P1(x,_)
                return QueryAtom(
                    [axiom.leftTerm(),
                     queryAtom.var1(),
                     NDNSVariable()], conceptList, roleList, individualList)

            elif axiom.leftTermExists() and \
             axiom.leftTermInverse() and \
             axiom.rightTermExists() and \
             not axiom.rightTermInverse() and \
             not isinstance(queryAtom.var1(), NDNSVariable) and \
             isinstance(queryAtom.var2(), NDNSVariable):
                #~ We have the following situations:
                #~ exists P1^- isA exists P
                #~ Return P1(_,x)
                return QueryAtom(
                    [axiom.leftTerm(),
                     NDNSVariable(),
                     queryAtom.var1()], conceptList, roleList, individualList)

            elif axiom.leftTermExists() and \
             not axiom.leftTermInverse() and \
             axiom.rightTermExists() and \
             axiom.rightTermInverse() and \
             not isinstance(queryAtom.var2(), NDNSVariable) and \
             isinstance(queryAtom.var1(), NDNSVariable):
                #~ We have the following situations:
                #~ exists P1 isA exists P^-
                #~ Return P1(y,_)

                return QueryAtom(
                    [axiom.leftTerm(),
                     queryAtom.var2(),
                     NDNSVariable()], conceptList, roleList, individualList)

            elif axiom.leftTermExists() and \
             axiom.leftTermInverse() and \
             axiom.rightTermExists() and \
             axiom.rightTermInverse() and \
             not isinstance(queryAtom.var2(), NDNSVariable) and \
             isinstance(queryAtom.var1(), NDNSVariable):
                #~ We have the following situations:
                #~ exists P1^- isA exists P^-
                #~ Return P1(_,y)
                return QueryAtom(
                    [axiom.leftTerm(),
                     NDNSVariable(),
                     queryAtom.var2()], conceptList, roleList, individualList)

            elif not axiom.leftTermExists() and \
             axiom.leftTermInverse() and \
             not axiom.rightTermExists() and \
             axiom.rightTermInverse() and \
             not isinstance(queryAtom.var1(), NDNSVariable) and \
             not isinstance(queryAtom.var2(), NDNSVariable):
                #~ We have the following situations:
                #~ P1^- isA P^-
                #~ Return P1(x,y)
                return QueryAtom(
                    [axiom.leftTerm(),
                     queryAtom.var1(),
                     queryAtom.var2()], conceptList, roleList, individualList)

            elif not axiom.leftTermExists() and \
             not axiom.leftTermInverse() and \
             not axiom.rightTermExists() and \
             axiom.rightTermInverse() and \
             not isinstance(queryAtom.var1(), NDNSVariable) and \
             not isinstance(queryAtom.var2(), NDNSVariable):
                #~ We have the following situations:
                #~ P1 isA P^-
                #~ Return P1(y,x)
                return QueryAtom(
                    [axiom.leftTerm(),
                     queryAtom.var2(),
                     queryAtom.var1()], conceptList, roleList, individualList)

            elif not axiom.leftTermExists() and \
             axiom.leftTermInverse() and \
             not axiom.rightTermExists() and \
             not axiom.rightTermInverse() and \
             not isinstance(queryAtom.var1(), NDNSVariable) and \
             not isinstance(queryAtom.var2(), NDNSVariable):
                #~ We have the following situations:
                #~ P1^- isA P
                #~ Return P1(y,x)
                return QueryAtom(
                    [axiom.leftTerm(),
                     queryAtom.var2(),
                     queryAtom.var1()], conceptList, roleList, individualList)
            #~ else:
            #~ Something is wrong
            #~ raise Exception("Something went wrong analyzing the axiom " + str(axiom))

        #~ If the code reach this point, it means the axiom couldn't be applied
        return None
Пример #21
0
 def lastModification(self,job):
     if job.trace_index==13050:#1293:
         print "FInd you!"
     if job.trace_index==0:
         return []
     if isinstance(self.l[job.trace_index], FunctionCallInfo):
         return None#The input should not be a job in FunctionCallInfo
     if job.trace_index==1:#begin
         if job.var.v in self.l[job.trace_index-1].param_list:
             self.TG.linkInnerEdges(job.trace_index,job.trace_index-1,job.var.simple_access_str())
         return []
     indexes=self.up_slice(job)
     if len(indexes)>0:
         pairs=self.findAllReferences(job.var,indexes,False)
         pairs.append((indexes[0]-1,job.var,False,0,len(indexes)))
         #(aIndex,q,True,idx+1,lb)
         defs=self.getDefs(pairs,indexes)
         for d,v in defs:
             print "In list definition:",d,self.l[d]
         for d,v in defs:
             def_type=self.matchDefinitionType(d,v)
             if def_type==Syntax.FOR:
                 self.TG.linkInnerEdges(job.trace_index,d,v.simple_access_str())
                 jobs=Syntax.generate_for_jobs(d, self.l[d].codestr, v)
                 return list(set(jobs))
             if def_type==Syntax.INC:#INC
                 self.TG.linkInnerEdges(job.trace_index,d,v.simple_access_str())
                 return [TaintJob(d,v)]
             elif def_type==Syntax.RAW_DEF:#RAW_DEF
                 self.TG.linkInnerEdges(job.trace_index,d,v.simple_access_str())
                 return []
             elif def_type==Syntax.NORMAL_ASSIGN:
                 self.TG.linkInnerEdges(job.trace_index,d,v.simple_access_str())
                 assign_handler=AssignmentHandler(self.l,self.TG)
                 jobs=assign_handler.getJobs(v,d,indexes)
                 return jobs
             elif def_type==Syntax.OP_ASSIGN:
                 self.TG.linkInnerEdges(job.trace_index,d,v.simple_access_str())
                 assign_handler=AssignmentHandler(self.l,self.TG)
                 jobs=assign_handler.getJobs(v,d,indexes)
                 jobs.append(TaintJob(d, v))
                 return jobs
             elif def_type == Syntax.RETURN_VALUE_ASSIGN:
                 self.TG.linkInnerEdges(job.trace_index,d,v.simple_access_str())
                 jobs=self.handleReturnAssignDirect(job.trace_index,d,v)
                 return jobs
             elif def_type==Syntax.SYS_LIB_DEF:
                 self.TG.linkInnerEdges(job.trace_index,d,v.simple_access_str())
                 jobs= Syntax.handle_sys_lib_def(d,v,self.l[d].codestr)
                 return list(set(jobs))
             else:
                 #job.traceIndex-->l.index(line)
                 #f(t->q) variable:t syntax:*(t->q)
                 #track the access variable t->q
                 #truncate the outter syntax (->q,*) minus ( ->q)= (*)
                 #use new syntax to checkArgDef----- var:t->q,syntax:*
                 #----------------
                 result=Syntax.isPossibleArgumentDefinition(self.l[d],v)
                 if result is not None:
                     rfl,p,childnum,callee,arg=result
                     if "->headindex" in p and "header_read"==callee:
                         print callee
                     jobs,b=self.checkArgDef(d,job.trace_index,job.trace_index,p,rfl,childnum,callee)
                     if b:
                         return jobs
     if len(indexes)>0:
         i=indexes[0]-1
     else:
         i=job.trace_index-1
     #l[i] must be an instance of FunctionCallInfo
     if i==0:#begin
         if job.var.v in self.l[i].param_list:
             self.TG.linkInnerEdges(job.trace_index,i,job.var.simple_access_str())
         return []
     elif self.l[i].get_func_name().split("::")[-1].strip() in self.l[i-1].codestr and self.l[i]==self.l[job.trace_index].get_func_call_info():#call point
         if job.var.v in self.l[i].param_list:
             self.TG.linkInnerEdges(job.trace_index,i,job.var.simple_access_str())
             return [TaintJob(i,job.var)]
         return []
     elif self.isMacroCall(i-1):
         if job.var.v in self.l[i].param_list:
             self.TG.linkInnerEdges(job.trace_index,i,job.var.simple_access_str())
             return [TaintJob(i,job.var)]
         return []
     return []
Пример #22
0
		def __indent(indentLevel):
			syntax = Syntax()
			
			return syntax.indent*indentLevel
Пример #23
0
    def __parseQuery(self, queryToParse, conceptList, roleList, individualList,
                     inequalitiesAllowed):

        syntax = Syntax()

        result = None

        if isinstance(queryToParse, CQ):
            #~ We directly add the CQ to self.__cqs and exit
            self.__cqs.add(queryToParse)

            #~ Find the freeVars of the current UCQ.
            #~ To do so, we collect all the free vars appearing in the inner UCQs.
            self.__freeVars.update(queryToParse.freeVars())

            return 0

        #~ If queryToParse is a string, we parse it by considering the parenthesis that close every expression
        #~ and analyse the resulting pyparsing.ParseResults.
        #~ If queryToParse is already a pyparsing.ParseResults, then we analise it directly.
        elif isinstance(queryToParse, str):
            parser = StringStart() + nestedExpr() + StringEnd()

            result = parser.parseString(queryToParse)

            #~ We consider only the first element of result, since, if it is a valid list,
            #~ then result is a nested list, and thus result[0] is the actual list we
            #~ are interested in.
            result = result[0]

        elif isinstance(queryToParse, (ParseResults, tuple, list)):
            result = queryToParse

        if result[0] == syntax.queryOr:
            #~ The list must contain "or" plus at least two inner UCQs,
            #~ starting from element result[1].
            if len(result) <= 2:
                raise Exception(
                    "The expression \"(or ... )\" must contain at least 2 internal UCQs."
                )

            for cq in result[1:]:

                if isinstance(cq, CQ):
                    self.__cqs.add(cq)
                else:
                    self.__cqs.add(
                        CQ(cq,
                           conceptList,
                           roleList,
                           individualList,
                           inequalitiesAllowed=self.__inequalitiesAllowed))

            #~ Check that all the inner UCQs have the same free variables
            for check in combinations(self.__cqs, 2):
                if check[0].freeVars() != check[1].freeVars():
                    raise Exception(
                        "The UCQs have different free variables in them!\n" +
                        str(check[0]) + "\n" + str(check[1]))

        else:
            #~ No specific keyword is used, thus it must be a CQ
            if len(result) == 1 and isinstance(result[0], CQ):
                #~ We directly add the CQ to self.__cqs and exit
                self.__cqs.add(result[0])

                #~ Find the freeVars of the current UCQ.
                #~ To do so, we collect all the free vars appearing in the inner UCQs.
                self.__freeVars.update(result[0].freeVars())

                return 0
            else:
                self.__cqs.add(
                    CQ(result,
                       conceptList,
                       roleList,
                       individualList,
                       inequalitiesAllowed=self.__inequalitiesAllowed))

        #~ Find the freeVars of the current UCQ.
        #~ To do so, we collect all the free vars appearing in the inner UCQs.
        for cq in self.__cqs:
            self.__freeVars.update(cq.freeVars())
Пример #24
0
 def checkArgDef(self,callsiteIndex,beginIndex,lowerBound,p,rfl,childnum,callee):
     if p==[] or isinstance(self.l[callsiteIndex+1],LineOfCode):#Abort non-pointer variable.
         return [],False
     #Note: funciton name and callee name may not be equal as there exist macro and function pointer
     #e.g. nread = abfd->iovec->bread (abfd, ptr, size);          
     indexes=self.slice_same_func_lines(callsiteIndex+2,lowerBound)#PlUS TWO("callsiteIndex+2")means
     #start from the first line of callee function.
     params=self.l[callsiteIndex+1].get_param_list().split(",")
     if len(params)-1<childnum:
         skip_va_arg_nums=childnum-len(params)
         res=self.check_va_arg_style(skip_va_arg_nums,indexes)
         if not res:
             print "BAD arg-->param number match!"
             print 1/0
         varname,indexes=res
         var= TaintVar(varname,p,rfl)
     else:
         #FIX ME following part should change for va_arg case
         #----------------------------------------------------------------------------------------#
         varname=params[int(childnum)].split("=")[0]
         #handle "=" cases like:
         #args_callback_command (name=0xbfffeb26 "swfdump0.9.2log/exploit_0_0", val=val@entry=0x0) at swfdump.c:200
         print self.l[callsiteIndex+1]
         var=TaintVar(varname,p,rfl)
         #---------------------------------------------------------------------------------------#
     
     pairs=self.findAllReferences(var,indexes,True)
     pairs.append((callsiteIndex+1,var,True,0,len(indexes)))
     defs=self.getDefs(pairs,indexes)
     for d,v in defs:
         print "%%%",self.l[d]
     for d,v in defs:
         #BUG
         def_type=self.matchDefinitionType(d,v)
         if def_type==Syntax.FOR:
             self.TG.linkCrossEdges(beginIndex,d,v.simple_access_str())
             jobs=Syntax.generate_for_jobs(d, self.l[d].codestr, v)
             return self.taintUp(jobs),True
         if def_type==Syntax.INC:#INC
             self.TG.linkCrossEdges(beginIndex,d,v.simple_access_str())
             jobs.append(TaintJob(d,v))
             jobs=list(set(jobs))
             return self.taintUp(jobs),True
         elif def_type==Syntax.RAW_DEF:#RAW_DEF
             self.TG.linkCrossEdges(beginIndex,d,v.simple_access_str())
             return [],True
         elif def_type==Syntax.NORMAL_ASSIGN:
             self.TG.linkCrossEdges(beginIndex,d,v.simple_access_str())
             assign_handler=AssignmentHandler(self.l,self.TG)
             jobs=assign_handler.getJobs(v,d,indexes)
             return self.taintUp(jobs),True
         elif def_type==Syntax.OP_ASSIGN:
             self.TG.linkCrossEdges(beginIndex,d,v.simple_access_str())
             assign_handler=AssignmentHandler(self.l,self.TG)
             jobs=assign_handler.getJobs(v,d,indexes)
             jobs.append(TaintJob(d, v))
             return self.taintUp(jobs),True
         elif def_type == Syntax.RETURN_VALUE_ASSIGN:
             self.TG.linkCrossEdges(beginIndex,d,v.simple_access_str())
             jobs=self.handleReturnAssignDirect(beginIndex,d,v)
             return jobs
         elif def_type==Syntax.SYS_LIB_DEF:
             self.TG.linkCrossEdges(beginIndex,d,v.simple_access_str())
             jobs= Syntax.handle_sys_lib_def(d,v,self.l[d].codestr)
             return self.taintUp(jobs),True
         else:
             #job.traceIndex-->l.index(line)
             #f(t->q) variable:t syntax:*(t->q)
             #track the access variable t->q
             #truncate the outter syntax (->q,*) minus ( ->q)= (*)
             #use new syntax to checkArgDef----- var:t->q,syntax:*
             #----------------
             result=Syntax.isPossibleArgumentDefinition(self.l[d],v)
             if result is not None:
                 rfl,p,childnum,callee,arg=result
                 jobs,b=self.checkArgDef(d,beginIndex,lowerBound,p,rfl,childnum,callee)
                 if b:
                     return self.taintUp(jobs),True
                         
     return [],False
Пример #25
0
# 载入源代码
lexical.load_source(open('test.c').read())
# 执行词法分析
lexical_success = lexical.execute()
# 打印结果
print('词法分析是否成功:\t', lexical_success)
if lexical_success:
    lexical_result = lexical.get_result()
    print()
    print('词法分析结果:')
    for i in lexical_result:
        print(i.type, i.str, i.line)
    print()

    # 开始执行语法分析
    syntax = Syntax()
    syntax.put_source(lexical_result)
    syntax_success = syntax.execute()
    print('语法分析和语义分析是否成功\t', syntax_success)
    if syntax_success:
        print()
        print('语义分析结果:\t')
        print('三地址代码:\t')
        i = -1
        for code in syntax.get_result().root.code:
            i += 1
            print(i, '  \t', code)
    else:
        print('错误原因:\t', syntax.get_error().info, syntax.get_error().line, '行')
else:
    print('错误原因:\t', lexical.get_error().info)