]> mj.ucw.cz Git - moe.git/commitdiff
Syntax constants localized to parser class.
authorTomas Gavenciak <gavento@matfyz.cz>
Mon, 24 May 2010 01:25:39 +0000 (21:25 -0400)
committerTomas Gavenciak <gavento@matfyz.cz>
Mon, 24 May 2010 01:25:39 +0000 (21:25 -0400)
t/moe/confparser.py

index ed73a1c804cbb781cffc9ec00d12f4e3735976b6..d7616d55980b72d7a6b157420f542a45c1805d89 100644 (file)
@@ -4,7 +4,7 @@ confparse.py
 
 Simple Moe configuration file syntax parser. 
 
-TODO: decide '()' around formulas
+TODO: decide neccessity of '()' in/around formulas
 TODO: check escaping in expressions
 TODO: should whitespace (incl. '\\n') be allowed (almost) everywhere?
       can comment be anywhere whitespace can?
@@ -42,38 +42,37 @@ ECHAR = re('([^\\{}]|\\\\|\\{|\\}|\\n)*')
 VARNAME = re('[a-zA-Z0-9-_]+(\.[a-zA-Z0-9-_]+)*')
 """
 
-import re, logging as log
+import re, itertools, logging as log
     
-class ConfSyntaxError(Exception):
-  # TODO: choose better superclass
+class ConfigSyntaxError(Exception):
+  # TODO: choose better superclass
   def __init__(self, msg, fname='<unknown>', line=None, column=None):
     self.msg = msg
     self.fname = fname
     self.line = line
     self.column = column
   def __str__(self):
-    return('ConfSyntaxError %s:%d:%d: %s'%(self.fname, self.line, self.column, self.msg))
-
-c_varname_sep = u'.'
-c_comment = u'#'
-c_open = u'{'
-c_close = u'}'
-c_ws = u' \t\n'
-c_sep = u';\n'
-c_nl = u'\n'
-c_if = u'if'
-c_and = u'and'
-c_or = u'or'
-c_not = u'not'
-c_eq = u'=='
-c_neq = u'!='
-c_set = u'='
-c_append = u'+='
+    return('ConfigSyntaxError %s:%d:%d: %s'%(self.fname, self.line, self.column, self.msg))
 
 "Variable name regexp, dots (separators) must be separated from edges and each other."
 re_VARNAME = re.compile(r'\A([A-Za-z0-9_-]+\.)*[A-Za-z0-9_-]+\Z')
 
-class ConfParser(object):
+class ConfigParser(object):
+  c_varname_sep = u'.'
+  c_comment = u'#'
+  c_open = u'{'
+  c_close = u'}'
+  c_ws = u' \t\n'
+  c_sep = u';\n'
+  c_nl = u'\n'
+  c_if = u'if'
+  c_and = u'and'
+  c_or = u'or'
+  c_not = u'not'
+  c_eq = u'=='
+  c_neq = u'!='
+  c_set = u'='
+  c_append = u'+='
   def __init__(self, f, tree, fname='<unknown>'):
     self.f = f         # Stream
     self.fname = fname # Filename
@@ -115,38 +114,38 @@ class ConfParser(object):
     p_BLOCK(self)
   def p_BLOCK(self):
     self.p_WS()
-    while not self.eof() and not f.peek(c_close):
+    while not self.eof() and not f.peek(self.c_close):
       self.p_STATEMENT()
       slef.p_WS()
-      if not self.peek() in c_sep:
+      if not self.peek() in self.c_sep:
        break
       self.p_SEP()
       self.p_WS()
   def p_WS():
     while not self.eof():
-      if self.peek() in c_ws:
+      if self.peek() in self.c_ws:
        self.next()
-      elif self.peeks(c_comment):
+      elif self.peeks(self.c_comment):
        self.p_COMMENT()
       else:
        break
   def p_COMMENT(self):
-    self.expect(c_comment, "'#' expected at the beginning of a comment.")
-    while not self.eof() and not self.nexts(c_nl):
+    self.expect(self.c_comment, "'#' expected at the beginning of a comment.")
+    while not self.eof() and not self.nexts(self.c_nl):
       pass
-    self.eof() or self.expect(c_nl)
+    self.eof() or self.expect(self.c_nl)
   def p_STATEMENT(self):
     self.p_WS()
-    if self.peeks(c_if):
+    if self.peeks(self.c_if):
       self.p_CONDITION()
     else:
       # for operation or subtree, read VARNAME
       varname = self.p_VARNAME()
       self.p_WS()
-      if self.nexts(c_open):
+      if self.nexts(self.c_open):
        self.p_BLOCK(varname)
        self.p_WS()
-       self.expect(c_close)
+       self.expect(self.c_close)
       else:
        self.p_OPERATION(varname)
   def p_SUBTREE(self, varname=None):
@@ -154,29 +153,29 @@ class ConfParser(object):
       self.p_WS()
       varname = self.p_VARNAME()
     self.p_WS()
-    self.expect(c_open)
+    self.expect(self.c_open)
     # backup and extend the variable name prefix 
     p = self.prefix
-    self.prefix = p + c_varname_sep + varname
+    self.prefix = p + self.c_varname_sep + varname
     self.p_BLOCK()
     self.prefix = p
     # close block and 
     self.p_WS()
-    self.expect(c_close)
+    self.expect(self.c_close)
   def p_OPERATION(self, varname=None):
     if not varname:
       self.p_WS()
       varname = self.p_VARNAME()
     self.p_WS()
-    if self.nexts(c_set):
+    if self.nexts(self.c_set):
       op = 'SET'
-    elif self.nexts(c_append):
+    elif self.nexts(self.c_append):
       op = 'APPEND'
     else:
       self.syntaxError('Unknown operation.')
     self.p_WS()
     exp = self.p_EXPRESSION()
-    v = self.tree.lookup((self.prefix+c_varname_sep+varname).lstrip(c_varname_sep))
+    v = self.tree.lookup((self.prefix+self.c_varname_sep+varname).lstrip(self.c_varname_sep))
     if self.conditions:
       cnd = self.conditions[-1]
     else:
@@ -184,17 +183,17 @@ class ConfParser(object):
     v.add_operation(op, cnd, exp, self.priority) 
   def p_CONDITION(self):
     self.p_WS()
-    self.expect(c_if)
+    self.expect(self.c_if)
     self.p_WS()
     f = p_FORMULA(self)
     cnd = ConfigCondition(f)
     self.conditions.append(cnd)
     # Parse a block
     self.p_WS()
-    self.expect(c_open)
+    self.expect(self.c_open)
     self.p_BLOCK()
     self.p_WS()
-    self.expect(c_close)
+    self.expect(self.c_close)
     # Cleanup
     self.conditions.pop()
   def p_VARNAME(self):
@@ -225,17 +224,17 @@ class ConfParser(object):
       if self.nexts(u'\\'):
        # Escape sequence
        c = self.next()
-       if c not in u'\\"n' + c_open + c_close:
+       if c not in u'\\"n' + self.c_open + self.c_close:
          self.syntax_error('Illeal escape sequence in expression')
        if c == 'n':
          expr.append(u'\n')
        else:
          expr.append(c)
        exl.append(c)
-      elif self.nexts(c_open):
+      elif self.nexts(self.c_open):
        # Parse a variable name in '{}'
        varname = self.p_VARNAME()
-        self.expect(c_close)
+        self.expect(self.c_close)
        exl.append(varname)
        expr.append(self.tree.lookup(varname))
       else:
@@ -257,12 +256,12 @@ class ConfParser(object):
     if self.nexts(u'('):
       f1 = self.p_FORMULA()
       self.p_WS()
-      if self.nexts(c_and):
+      if self.nexts(self.c_and):
        f2 = self.p_FORMULA()
        self.p_WS()
        self.expect(u')')
        return ('AND', f1, f2)
-      elif self.nexts(c_or):
+      elif self.nexts(self.c_or):
        f2 = self.p_FORMULA()
        self.p_WS()
        self.expect(u')')
@@ -272,7 +271,7 @@ class ConfParser(object):
        return f1
       else:
        self.syntax_error("Logic operator or ')' expected")
-    elif self.nexts(c_not):
+    elif self.nexts(self.c_not):
       # 'not' formula
       f = self.p_FORMULA()
       return ('NOT', f)
@@ -280,11 +279,11 @@ class ConfParser(object):
       # Should be (in)equality condition
       e1 = self.p_EXPRESSION()
       self.p_WS()
-      if self.nexts(c_eq):
+      if self.nexts(self.c_eq):
        self.p_WS()
        e2 = self.p_EXPRESSION()
        return ('==', e1, e2)
-      elif self.nexts(c_neq):
+      elif self.nexts(self.c_neq):
        self.p_WS()
        e2 = self.p_EXPRESSION()
        return ('!=', e1, e2)