Somewhat working version.
4 Author: Eugen Sawin <sawine@informatik.uni-freiburg.de>
22 class Operator(object):
23 def __init__(self, id, arity, values):
30 out = str(self.values[0])
32 out = self.id + str(self.values[0])
36 out = "(" + str(self.values[0]) + " " + self.id + " " + str(self.values[1]) + ")"
41 def __init__(self, values):
42 Operator.__init__(self, NOT, Not.arity, values)
48 def __init__(self, values):
49 Operator.__init__(self, AND, And.arity, values)
53 def __init__(self, values):
54 Operator.__init__(self, OR, Or.arity, values)
58 def __init__(self, values):
59 Operator.__init__(self, IMP, Imp.arity, values)
63 def __init__(self, values):
64 Operator.__init__(self, EQ, Eq.arity, values)
68 def __init__(self, values):
69 Operator.__init__(self, BOX, Box.arity, values)
71 class Diamond(Operator):
73 def __init__(self, values):
74 Operator.__init__(self, DIAMOND, Diamond.arity, values)
76 class Variable(Operator):
78 def __init__(self, values):
79 Operator.__init__(self, VARIABLE, Variable.arity, values)
83 def __init__(self, values):
84 Operator.__init__(self, LB, Lb.arity, values)
88 def __init__(self, values):
89 Operator.__init__(self, RB, Rb.arity, values)
91 class Formula(object):
95 TOKENS = {re.compile("\("): Lb,
100 re.compile("->"): Imp,
101 re.compile("<->"): Eq,
102 re.compile("\[\]"): Box,
103 re.compile("<>"): Diamond,
104 re.compile("[a-z]+"): Variable}
106 class Scanner(object):
107 def __init__(self, tokens, source=None):
111 while self.i < len(self.source):
113 for p, token in self.tokens.iteritems():
114 m = p.match(self.source[self.i:])
118 return (token, value)
121 def reset(self, source):
136 SYNTAX = ((Variable,),
147 def __init__(self, parent, value):
151 def addChild(self, value):
152 self.children.append(self, node)
154 class Parser(object):
155 def __init__(self, syntax, scanner):
157 self.scanner = scanner
158 def parse(self, source):
159 table = {(S, Variable): 0,
168 (A, Variable, And): 5,
169 (A, Variable, Or): 6,
170 (A, Variable, Imp): 7,
171 (A, Variable, Eq): 8,
172 (A, Not, Variable, And): 5,
173 (A, Not, Variable, Or): 6,
174 (A, Not, Variable, Imp): 7,
175 (A, Not, Variable, Eq): 8}
180 self.scanner.reset(source)
181 (token, value) = self.scanner.next()
182 (lookahead, la_value) = self.scanner.next()
183 (lookahead2, la2_value) = self.scanner.next()
185 while token and len(stack):
188 tree_nodes.append((token, value))
190 #tree_nodes.append((stack.pop(), value))
191 (token, value) = (lookahead, la_value)
192 (lookahead, la_value) = (lookahead2, la2_value)
193 #(lookahead, _) = self.scanner.next()
194 (lookahead2, la2_value) = self.scanner.next()
197 if (top, token) in table:
198 action = table[(top, token)]
199 elif (top, token, lookahead) in table:
200 action = table[(top, token, lookahead)]
201 elif (top, token, lookahead, lookahead2) in table:
202 action = table[(top, token, lookahead, lookahead2)]
209 stack.extend(reversed(self.syntax[action]))
210 accepted = accepted and not len(stack)
211 return (accepted, out, tree_nodes)
213 class SyntaxTree(object):
214 def __init__(self, seq, tree_nodes):
219 self.root = self.compile(seq, tree_nodes)[0]
221 def compile(self, seq, tree_nodes):
228 c, v = tree_nodes.pop()
230 c, v = tree_nodes.pop()
231 stack.append(Variable(v))
233 stack.append(Not(self.compile(seq, tree_nodes)))
235 stack.extend(self.compile(seq, tree_nodes))
237 stack.append(Box(self.compile(seq, tree_nodes)))
239 stack.append(Diamond(self.compile(seq, tree_nodes)))
241 stack.append(And(self.compile(seq, tree_nodes)))
243 stack.append(Or(self.compile(seq, tree_nodes)))
245 stack.append(Imp(self.compile(seq, tree_nodes)))
247 stack.append(Eq(self.compile(seq, tree_nodes)))
251 def compile_(self, tree_nodes):
256 for n, v in (tree_nodes):
260 if len(table) < n.arity:
261 print "appending unfinished ", n
264 args = table[:n.arity]
267 table = table[n.arity:]
270 if len(unfinished) and unfinished[-1].arity <= len(table):
272 print "finishing ", n
273 args = table[:n.arity]
274 table = table[n.arity:]
282 args = parse_arguments()
283 scanner = Scanner(TOKENS)
284 parser = Parser(SYNTAX, scanner)
285 (accepted, out, tree_nodes) = parser.parse(args.formula)
286 tree = SyntaxTree(out, tree_nodes)
289 from argparse import ArgumentParser
291 def parse_arguments():
292 parser = ArgumentParser(description="Parses simple modal logic syntax.")
293 parser.add_argument("formula", help="your formula")
294 return parser.parse_args()
296 if __name__ == "__main__":