def mine_grammar(self): grammar = extend_grammar(self.QUERY_GRAMMAR) grammar["<action>"] = [self.action] query = "" for field in self.fields: field_symbol = new_symbol(grammar, "<" + field + ">") field_type = self.fields[field] if query != "": query += "&" query += field_symbol if isinstance(field_type, str): field_type_symbol = "<" + field_type + ">" grammar[field_symbol] = [field + "=" + field_type_symbol] if field_type_symbol not in grammar: # Unknown type grammar[field_type_symbol] = ["<text>"] else: # List of values value_symbol = new_symbol(grammar, "<" + field + "-value>") grammar[field_symbol] = [field + "=" + value_symbol] grammar[value_symbol] = field_type grammar["<query>"] = [query] # Remove unused parts for nonterminal in unreachable_nonterminals(grammar): del grammar[nonterminal] assert is_valid_grammar(grammar) return grammar
def _duplicate_context(grammar, orig_grammar, symbol, expansion, depth, seen): for i in range(len(grammar[symbol])): if expansion is None or grammar[symbol][i] == expansion: new_expansion = "" for (s, c) in expansion_to_children(grammar[symbol][i]): if s in seen: # Duplicated already new_expansion += seen[s] elif c == [] or depth == 0: # Terminal symbol or end of recursion new_expansion += s else: # Nonterminal symbol - duplicate # Add new symbol with copy of rule new_s = new_symbol(grammar, s) grammar[new_s] = copy.deepcopy(orig_grammar[s]) # Duplicate its expansions recursively # {**seen, **{s: new_s}} is seen + {s: new_s} _duplicate_context(grammar, orig_grammar, new_s, expansion=None, depth=depth - 1, seen={ **seen, **{ s: new_s } }) new_expansion += new_s grammar[symbol][i] = new_expansion
def add_group(self, locals, exclusive): kwargs = locals["kwargs"] if self.log: print(kwargs) required = kwargs.get("required", False) group = new_symbol(self.grammar, "<group>") if required and exclusive: group_expansion = group if required and not exclusive: group_expansion = group + "+" if not required and exclusive: group_expansion = group + "?" if not required and not exclusive: group_expansion = group + "*" self.grammar[START_SYMBOL][0] = group_expansion + \ self.grammar[START_SYMBOL][0] self.grammar[group] = [] self.current_group = group
if __package__ is None or __package__ == "": from Grammars import new_symbol else: from .Grammars import new_symbol if __name__ == "__main__": cpp_grammar = { "<start>": ["cc -c<options> " + filename], "<options>": ["<option>", "<options><option>"], "<option>": [] } for id in cpp_ids: s = new_symbol(cpp_grammar, "<" + id + ">") cpp_grammar["<option>"].append(s) cpp_grammar[s] = [" -D" + id] cpp_grammar if __name__ == "__main__": assert is_valid_grammar(cpp_grammar) # #### Part 3: C Preprocessor Configuration Fuzzing if __name__ == "__main__": print('\n#### Part 3: C Preprocessor Configuration Fuzzing')
def function_symbol(self, function_name, grammar): return new_symbol(grammar, "<" + function_name + ">")
def var_symbol(self, function_name, var, grammar): return new_symbol(grammar, "<" + function_name + "-" + var + ">")
def new_state_symbol(self, grammar): return new_symbol(grammar, self.START_STATE)