def getGrammarObject(fileStream): """ Produces a JSGFGrammar object from a stream of text, the grammar object has a set of public rules and regular rules :param fileStream: file object containing the contents of the grammar file :type fileStream: file object :returns: JSGFGrammar object """ linegenerator = fileStream lines = linegenerator.readlines() for i in range(len(lines)): lines[i] = nocomment(lines[i]) # buffer will accumulate lines until a fully parseable piece is found buffer = "" grammar = gram.Grammar() for line in lines: buffer += line match = next(StartSymbol.scanString(buffer), None) while match: tokens, start, end = match #print 'rule dict is', tokens.asDict() if 'public' in tokens.keys(): grammar.addPublicRule( gram.Rule(tokens.identifier, list(tokens.ruleDef))) grammar.addRule(gram.Rule(tokens.identifier, list(tokens.ruleDef))) buffer = buffer[end:] match = next(StartSymbol.scanString(buffer), None) return grammar
def foundOptionalGroup(s, loc, toks): """ PyParsing action to run when an optional group is found. :returns: Optional object containing all elements in the group """ #print 'optional item is', toks.optionalItem if len(list(toks[0])) > 1: return gram.Optional(list(toks[0])) else: return gram.Optional(toks.optionalItem[0])
def foundNonterminal(s, loc, toks): """ PyParsing action to run when a nonterminal reference is found. :returns: NonTerminal object representing the NT reference found """ return gram.NonTerminal(list(toks)[0])
def foundPair(s, loc, toks): """ PyParsing action to run when a pair of alternatives are found. :returns: Disjunction object containing all disjuncts that have been accumulated so far """ #print 'found pair', toks.dump() #print 'disj1 is', list(toks.disj1), 'disj2 is', list(toks.disj2) firstAlternative = list(toks.disj1) secondAlternative = list(toks.disj2) if len(firstAlternative) > 1: disj = [firstAlternative] else: disj = firstAlternative if len(secondAlternative) == 1: if isinstance(secondAlternative[0], gram.Disjunction): #print 'found disjuncts in second alt', secondAlternative[0].disjuncts disj.extend(secondAlternative[0].disjuncts) else: disj.append(secondAlternative[0]) else: disj.append(secondAlternative) disj = gram.Disjunction(disj) #print 'returing the pair', disj return disj
if __name__ == '__main__': argParser = argparse.ArgumentParser() argParser.add_argument('grammarFile') argParser.add_argument('iterations', type=int, nargs=1, help='number of strings to generate') args = argParser.parse_args() fileStream = open(args.grammarFile) numIterations = args.iterations[0] grammar = parser.getGrammarObject(fileStream) if len(grammar.publicRules) != 1: #x = raw_input('Found more than one public rule. Generate a random string between them?\n') #if x == 'y': ### This next chunk has been de-indented disjuncts = [] for rule in grammar.publicRules: rhs = rule.rhs disjuncts.append(rhs) newStartSymbol = gram.Disjunction(disjuncts) for i in range(numIterations): print processRHS(newStartSymbol) ### #else: #sys.exit('Bye') else: startSymbol = grammar.publicRules[0] for i in range(numIterations): expansions = processRHS(startSymbol.rhs) print expansions