Source code for generator

"""
This modules provides an simple interface for generating
algorithm for forbidden pattern from an intermediate language:

    slist           : statement
                    | slist statement


    statement       : LPAREN plist RPAREN IN NAME INVSTMT
                    | NAME MINUS NAME ARROW NAME  INVSTMT


    plist           : plist COMMA NAME
                    | NAME

Please see: http://www.dabeaz.com/ply/ply.html for more details of ply.

"""

__author__ = 'Alexander Weigl <weigla@fh-trier.de>'
__date__ = '2012-06-13'

import ply.lex  as lex
import ply.yacc as yacc

#__all__ = ["generateCode"]

reserved = {
    'in': 'IN',
}

tokens = ["INVSTMT", "NAME", "LPAREN", "RPAREN", "COMMA", "ARROW", "MINUS"] + list(reserved.values())

t_LPAREN = r"\("
t_RPAREN = r"\)"
t_COMMA = r","
t_ARROW = r"->"
t_MINUS = r"-"
t_ignore = " \t"


[docs]def t_NAME(t): r'[a-zA-Z_][a-zA-Z_0-9]*' t.type = reserved.get(t.value, 'NAME') # Check for reserved words return t
[docs]def t_INVSTMT(t): r'\[.*?\]' t.value = t.value.strip("[]") return t
[docs]def t_newline(t): r'\n+' t.lexer.lineno += t.value.count("\n")
[docs]def t_error(t): print("Illegal character '%s'" % t.value[0]) t.lexer.skip(1)
lex.lex() #start symbol start = "slist"
[docs]def p_slist_stmt(t): '''slist : statement''' print("recur anchor slist", type(t[1])) t[1].innerBlock = "return True" t[0] = t[1]
[docs]def p_slist_recur(t): '''slist : slist statement''' t[1].innerBlock = t[2] #building a chained list t[0] = t[1]
[docs]def p_statement_in(t): '''statement : LPAREN plist RPAREN IN NAME INVSTMT''' print("InStatement") t[0] = InStatement(t[2], t[5], t[6])
[docs]def p_statement_bfs(t): '''statement : NAME MINUS NAME ARROW NAME INVSTMT''' t[0] = BfsStatement(t[1], t[3], t[5], t[6])
[docs]def p_plist_recur(t): '''plist : plist COMMA NAME''' t[1].append(t[3]) t[0] = t[1]
[docs]def p_plist_NAME(t): '''plist : NAME''' t[0] = list(( t[1], ))
[docs]def p_error(t): print(t) print("Syntax error at '%s'" % t.value)
yacc.yacc()
[docs]def indent(string, level=1, fmt=" " * 4): s = fmt * level return s + string.replace("\n", "\n" + s)
[docs]def codegen(tupl): code = "" newline = False print(tupl) for obj in tupl: if type(obj) is tuple: s = indent(codegen(obj)) code += "\n" + s else: if newline: code += "\n" newline = True code += str(obj) return code
[docs]class InStatement(object): def __init__(self, vars, inSet, invariant, innerBlock=""): self.vars = vars self.inSet = inSet self.invariant = "True" if invariant == "" else invariant self.innerBlock = innerBlock def __str__(self): """code generation""" return codegen(( "for (%s) in %s:" % (",".join(self.vars), self.inSet), ("if %s:" % self.invariant, (self.innerBlock,))))
[docs]def BfsStatement(object): def __init__(self, start, word, end, invariant, innerBlock=""): self.start = start self.word = word self.end = end self.invariant = invariant self.innerBlock = innerBlock def __str__(self): ib = indent(str(self.innerBlock), 2) return "for (%s,%s) in dea.search(%s):\n\tif %s:\n%s" % ( self.end, self.word, self.start, self.invariant, ib )
[docs]def generateCode(spec): """ :param spec: a str :return: the generated code with a str: """ return str(yacc.parse(spec))
if __name__ == "__main__": for s in ("q -v-> q", "[]", "[q=p]", "(p,r,a) in T"): lex.input(s) while True: tok = lex.token() print(tok) if not tok: break print() p = ( yacc.parse("(q,p,r) in Q []") ) print(type(p)) print(p)

This Page