Permalink
Browse files

lots of shift reduce conflicts.

  • Loading branch information...
1 parent e5412ee commit 3e8f21d8c9d338580f48ad258a635a19d9cc9c28 @uberj committed Oct 24, 2012
Showing with 476 additions and 0 deletions.
  1. 0 README.md
  2. +4 −0 README.mkd
  3. +34 −0 invfilter.py
  4. +68 −0 invlex.py
  5. +199 −0 invparse.py
  6. +139 −0 parser_tests.py
  7. +32 −0 utils.py
View
No changes.
View
@@ -0,0 +1,4 @@
+Requirements:
+```
+ply
+```
View
@@ -0,0 +1,34 @@
+class _Filter(object):
+ """The Base class of different filters. Implement these methods
+ """
+ def __str__(self):
+ return self.value
+
+ def __repr__(self):
+ return "<{1}>".format(self.__class__, self)
+
+ def compile_Q(self, ntype):
+ pass
+
+class TextFilter(_Filter):
+ def __init__(self, rvalue):
+ self.value = rvalue
+ self.Q = self.compile_Q(rvalue)
+
+ def compile_Q(self, value):
+ pass
+
+class REFilter(TextFilter):
+ def compile_Q(self, value):
+ pass
+
+class DirectiveFilter(_Filter):
+ def __init__(self, rvalue, directive, dvalue):
+ self.value = rvalue
+ self.directive = directive
+ self.dvalue = dvalue
+ self.Q = self.compile_Q(directive, dvalue)
+
+ def compile_Q(self, directive, dvalue):
+ pass
+
View
@@ -0,0 +1,68 @@
+import pdb
+import re
+import ply.lex as lex
+from invfilter import *
+
+class InvLexer(object):
+
+ tokens = (
+ 'TEXT','DIRECTIVE', 'RE',
+ 'AND','NOT','OR',
+ 'LPAREN','RPAREN',
+ )
+
+ # Tokens
+
+ t_LPAREN = r'\('
+ t_RPAREN = r'\)'
+
+ def t_NOT(self, t):
+ r'-'
+ t.value = 'NOT'
+ return t
+
+ def t_AND(self, t):
+ r'AND'
+ return t
+
+ def t_OR(self, t):
+ r'OR'
+ return t
+
+ def t_DIRECTIVE(self, t):
+ r'([a-zA-Z_]+)=:([a-zA-Z0-9_\.]+)'
+ r = r'([a-zA-Z_]+)=:([a-zA-Z0-9_\.]+)'
+ match = re.compile(r).match(t.value)
+ directive = match.groups(1)[0]
+ dvalue = match.groups(1)[1]
+ t.value = DirectiveFilter(t.value, directive, dvalue)
+ return t
+
+ def t_RE(self, t):
+ r'/[a-zA-Z0-9_\.]+'
+ r = r'/([a-zA-Z0-9_\.]+)'
+ match = re.compile(r).match(t.value)
+ rvalue = match.groups(1)[0]
+ t.value = REFilter(rvalue)
+ return t
+
+ def t_TEXT(self, t):
+ r'[a-zA-Z0-9_\.]+'
+ t.value = TextFilter(t.value)
+ return t
+
+
+ # Ignored characters
+ t_ignore = " \t"
+
+ def t_newline(self, t):
+ r'\n+'
+ t.lexer.lineno += t.value.count("\n")
+
+ def t_error(self, t):
+ print("Illegal character '%s'" % t.value[0])
+ t.lexer.skip(1)
+
+ # Build the lexer
+ def build_lexer(self, **kwargs):
+ self.lexer = lex.lex(module=self, **kwargs)
View
@@ -0,0 +1,199 @@
+import pdb
+from invlex import InvLexer
+import ply.yacc as yacc
+
+class BOP(object):
+ def __init__(self, value, l_child, r_child):
+ self.value = value
+ self.l_child = l_child
+ self.r_child = r_child
+
+ def __str__(self):
+ return self.value
+
+ def __repr__(self):
+ return "<BOP {0}>".format(self.value)
+
+class UOP(object):
+ def __init__(self, value, child):
+ self.value = value
+ self.child = child
+
+ def __str__(self):
+ return self.value
+
+ def __repr__(self):
+ return "<UOP {0}>".format(self.value)
+
+
+precedence = (
+ ('left', 'AND'),
+ ('right', 'NOT'),
+ )
+
+def p_statement_expr(p):
+ 'statement : expression'
+ p[0] = p[1]
+
+def p_expression_expr_factor(p):
+ 'expression : expression factor'
+ p[0] = BOP('AND', p[1], p[2])
+
+def p_expression_factor(p):
+ 'expression : factor'
+ p[0] = p[1]
+
+def p_expression_binop(p):
+ '''expression : expression AND expression
+ | expression NOT expression
+ | expression OR expression
+ | LPAREN expression RPAREN expression
+ | expression LPAREN expression RPAREN'''
+ if p[2] == 'NOT':
+ p3_invert = UOP('NOT', p[3])
+ p[0] = BOP('AND', p[1], p3_invert)
+ elif p[2] == 'AND' or p[2] == 'OR':
+ p[0] = BOP(p[2], p[1], p[3])
+ elif p[1] == '(': # Matched 'LPAREN expression RPAREN expression'
+ p[0] = BOP('AND', p[2], p[4])
+ elif p[2] == '(':
+ p[0] = BOP('AND', p[1], p[3])
+
+
+def p_expression_uminus(p):
+ 'expression : NOT expression'
+ p[0] = UOP('NOT', p[2])
+
+
+def p_expression_group(p):
+ 'expression : LPAREN expression RPAREN'
+ p[0] = p[2]
+
+def p_factor(p):
+ '''factor : NOT term
+ | term'''
+ if len(p) == 3:
+ p[0] = UOP('NOT', p[2])
+ else:
+ p[0] = p[1]
+
+def p_term_DIRECTIVE(p):
+ 'term : DIRECTIVE'
+ p[0] = p[1]
+
+def p_term_TEXT(p):
+ 'term : TEXT'
+ p[0] = p[1]
+
+def p_term_RE(p):
+ 'term : RE'
+ p[0] = p[1]
+
+def p_error(p):
+ if not p:
+ print "Syntax error at end of line"
+ else:
+ print "Syntax error at '{0}'".format(p.value)
+
+def build_parser():
+ lexer = InvLexer()
+ lexer.build_lexer()
+ tokens = lexer.tokens
+ p = yacc.yacc()
+ def parse(s):
+ return yacc.parse(s, lexer=lexer.lexer)
+ return parse
+
+if __name__ == "__main__":
+ lexer = InvLexer()
+ lexer.build_lexer()
+ tokens = lexer.tokens
+ p = yacc.yacc()
+
+ """
+ s = "a b"
+ print
+ print '-' * 10
+ s = "a OR -b AND c"
+ print s
+ yacc.parse(s, lexer=lexer.lexer)
+ print
+ print '-' * 10
+ print s
+ s = "(a OR b) AND c"
+ p.parse(s)
+ print
+ print '-' * 10
+
+ s = "-(a OR b) AND c"
+ print s
+ p.parse(s)
+ print
+ print '-' * 10
+
+ s = "type=:a vlan=:b"
+ print s
+ p.parse(s)
+ print
+ print '-' * 10
+
+ s = "/a"
+ print s
+ p.parse(s)
+ print
+ print '-'*10
+
+ s = "(a) (b)"
+ print s
+ p.parse(s)
+ print
+ print '-'*10
+
+ s = "a (b)"
+ print s
+ p.parse(s)
+ print
+ print '-'*10
+
+ s = "(a) b"
+ print s
+ p.parse(s)
+ print
+ print '-'*10
+
+ s = "(((a)) (b))"
+ print s
+ p.parse(s)
+ print
+ print '-'*10
+
+ s = "(a b c)"
+ print s
+ p.parse(s)
+ print
+ print '-'*10
+
+ s = "a b d OR c f g"
+ print s
+ p.parse(s)
+ print
+ print '-'*10
+
+ s = "(a (b c))"
+ print s
+ p.parse(s)
+ print
+ print '-'*10
+
+ s = "a -(c OR b)"
+ print s
+ p.parse(s)
+ print
+ print '-'*10
+
+ s = "a AND"
+ print s
+ p.parse(s)
+ print
+ print '-'*10
+ """
Oops, something went wrong.

0 comments on commit 3e8f21d

Please sign in to comment.