From 748dba3fceb225606533cbd836ea4642344b96ac Mon Sep 17 00:00:00 2001 From: Tomas Gavenciak Date: Sun, 23 May 2010 21:25:39 -0400 Subject: [PATCH] Syntax constants localized to parser class. --- t/moe/confparser.py | 97 ++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 49 deletions(-) diff --git a/t/moe/confparser.py b/t/moe/confparser.py index ed73a1c..d7616d5 100644 --- a/t/moe/confparser.py +++ b/t/moe/confparser.py @@ -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 a better superclass def __init__(self, msg, fname='', 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=''): 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) -- 2.39.2