X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=t%2Fmoe%2Fconfig_parser.py;h=2da6facfa2daa9062c78b2cfc9d9fe52cdddaf16;hb=3b2c0c783bf7284037f4c5c5ffd6582ee7b1f89c;hp=73b5406cbd6433e62712bde7b6b2f7f8717d3ae4;hpb=d8de72934717e8f287301c07d2ec70f1ca332e79;p=moe.git diff --git a/t/moe/config_parser.py b/t/moe/config_parser.py index 73b5406..2da6fac 100644 --- a/t/moe/config_parser.py +++ b/t/moe/config_parser.py @@ -1,47 +1,44 @@ -""" -config_parser.py ------------- - +r""" Simple Moe configuration file syntax parser. -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? +Generally, whitespace and comments are alowed everywhere except in variable names and inside expressions, +``\\n`` ends a ``COMMENT``. -Generally, whitespace and comments are alowed everywhere except in variable names and inside expressions. -Also, COMMENT must not contain '\\n'. +``FILE``, ``BLOCK``, ``STATEMENT``, ``OPERATION``, ``SUBTREE``, ``CONDITION``, ``FORMULA``, ``AND``, ``OR`` +and ``NOT`` ignore any preceding whitespace. -FILE, BLOCK, STATEMENT, OPERATION, SUBTREE, CONDITION, FORMULA, AND, OR and NOT eat any preceding whitespace. TODO: check? +.. highlight:: none -The configuration syntax is the following: +The configuration syntax is the following:: -FILE = BLOCK -BLOCK = WS | STATEMENT ( SEP STATEMENT )* + FILE = BLOCK + BLOCK = WS | STATEMENT ( SEP STATEMENT )* -SEP = ( '\\n' | ';' ) -WS = ( ' ' | '\\t' | '\\n' | COMMENT )* + SEP = ( '\n' | ';' ) + WS = ( ' ' | '\t' | '\n' | COMMENT )* -COMMENT = re('#[^\\n]*\\n') + COMMENT = re('#[^\n]*\n') -STATEMENT = CONDITION | OPERATION | SUBTREE + STATEMENT = CONDITION | OPERATION | SUBTREE -OPERATION = WS VARNAME WS ( '=' | '+=' ) WS EXPRESSION -SUBTREE = WS VARNAME WS '{' BLOCK WS '}' -CONDITION = WS 'if' FORMULA WS '{' BLOCK WS '}' + OPERATION = WS VARNAME WS ( '=' | '+=' ) WS EXPRESSION + SUBTREE = WS VARNAME WS '{' BLOCK WS '}' + CONDITION = WS 'if' FORMULA WS '{' BLOCK WS '}' -FORMULA = WS (( EXPRESSION WS ( '!=' | '==' ) WS EXPRESSION ) | '(' AND WS ')' | '(' OR WS ')' | NOT ) -AND = FORMULA WS 'and' FORMULA -OR = FORMULA WS 'or' FORMULA -NOT = WS 'not' FORMULA + FORMULA = WS (( EXPRESSION WS ( '!=' | '==' ) WS EXPRESSION ) | + '(' AND WS ')' | '(' OR WS ')' | NOT ) + AND = FORMULA WS 'and' FORMULA + OR = FORMULA WS 'or' FORMULA + NOT = WS 'not' FORMULA -NOTE: ';' or '\n' is currently required even after CONDITION and SUBTREE block - TODO: change to OPERATION only -NOTE: Formula may contain additional/extra parentheses + EXPRESSION = '"' ( ECHAR | '{' VARNAME '}' )* '"' | re"'[^'\n]*'" | VARNAME + ECHAR = re('([^\{}]|\\|\{|\}|\\n)*') + VARNAME = re('[a-zA-Z0-9-_]+(\.[a-zA-Z0-9-_]+)*') -EXPRESSION = '"' ( ECHAR | '{' VARNAME '}' )* '"' | re"'[^'\\n]*'" | VARNAME -ECHAR = re('([^\\{}]|\\\\|\\{|\\}|\\n)*') -VARNAME = re('[a-zA-Z0-9-_]+(\.[a-zA-Z0-9-_]+)*') +.. todo:: should whitespace (incl. '\n') be allowed (almost) everywhere? + can comment be anywhere whitespace can? +.. note:: ';' or '\\n' is currently required even after CONDITION and SUBTREE block +.. note:: Formula can contain additional/unnecessary parentheses """ import re, types, itertools, logging as log @@ -50,6 +47,16 @@ import traceback import moe.config as cf +def config_escape(s): + """ + Escape any ``{``, ``}``, ``"`` and ``\\`` in the given string, making it safe for parsing. + """ + s = s.replace('\\', '\\\\') + s = s.replace('{', '\\{') + s = s.replace('}', '\\}') + s = s.replace('"', '\\"') + return s + class ConfigSyntaxError(cf.ConfigError): def __init__(self, msg, source='', line=None, column=None): @@ -242,8 +249,10 @@ class ConfigParser(object): op = 'SET' elif self.nexts(self.c_append): op = 'APPEND' + elif self.eof(): + self.syntax_error('Unexpected end of file.') else: - self.syntax_error('Unknown operation.') + self.syntax_error('Unknown operation: %r...', self.peek(10)) self.p_WS() exp = self.p_EXPRESSION() vname = (self.prefix+self.c_varname_sep+varname).lstrip(self.c_varname_sep)