# Of course you can modify the Abstract Syntax Tree to your purpose. # # Copyright 2004, by Alberto Santini http://www.albertosantini.it/chess/ # from pyparsing import alphanums, nums, quotedString from pyparsing import Combine, Forward, Group, Literal, oneOf, OneOrMore, Optional, Suppress, ZeroOrMore, White, Word from pyparsing import ParseException # # define pgn grammar # tag = Suppress("[") + Word(alphanums) + Combine(quotedString) + Suppress("]") comment = Suppress("{") + Word(alphanums + " ") + Suppress("}") dot = Literal(".") piece = oneOf("K Q B N R") file_coord = oneOf("a b c d e f g h") rank_coord = oneOf("1 2 3 4 5 6 7 8") capture = oneOf("x :") promote = Literal("=") castle_queenside = Literal("O-O-O") | Literal("0-0-0") | Literal("o-o-o") castle_kingside = Literal("O-O") | Literal("0-0") | Literal("o-o") move_number = Optional(comment) + Word(nums) + dot m1 = file_coord + rank_coord # pawn move e.g. d4 m2 = file_coord + capture + file_coord + rank_coord # pawn capture move e.g. dxe5 m3 = file_coord + "8" + promote + piece # pawn promotion e.g. e8=Q m4 = piece + file_coord + rank_coord # piece move e.g. Be6 m5 = piece + file_coord + file_coord + rank_coord # piece move e.g. Nbd2 m6 = piece + rank_coord + file_coord + rank_coord # piece move e.g. R4a7
geo_value = Forward() # TODO Either a Geo or a reference to a Geo url_parser = Forward() # TODO context_query = Forward( ) # TODO A way to find a match between pairs of processors. A pair of Processor Selectors domain_definition = Forward( ) # TODO Domain definition. Either a Category Hierarchy name or a numeric interval (with open closed) parameter_value = Forward( ) # TODO Parameter Value. Could be "expression_with_parameters" indicator_expression = Forward() # TOKENS # Separators and operators (arithmetic and boolean) lparen, rparen, lbracket, rbracket, lcurly, rcurly, dot, equals, hash = map( Literal, "()[]{}.=#") double_quote = Literal('"') single_quote = Literal("'") quote = oneOf('" ' '') # Double quotes, single quotes signop = oneOf('+ -') multop = oneOf('* / // %') plusop = oneOf('+ -') expop = oneOf('^ **') comparisonop = oneOf("< <= > >= == != <>") andop = CaselessKeyword("AND") orop = CaselessKeyword("OR") notop = CaselessKeyword("NOT") processor_factor_separator = Literal(":") conditions_opening = Literal("?") conditions_closing = Literal("?") # Boolean constants
def formula_grammar(table): """ Construct a parser for molecular formulas. :Parameters: *table* = None : PeriodicTable If table is specified, then elements and their associated fields will be chosen from that periodic table rather than the default. :Returns: *parser* : pyparsing.ParserElement. The ``parser.parseString()`` method returns a list of pairs (*count,fragment*), where fragment is an *isotope*, an *element* or a list of pairs (*count,fragment*). """ # Recursive composite = Forward() mixture = Forward() # whitespace and separators space = Optional(White().suppress()) separator = space+Literal('+').suppress()+space # Lookup the element in the element table symbol = Regex("[A-Z][a-z]*") symbol = symbol.setParseAction(lambda s,l,t: table.symbol(t[0])) # Translate isotope openiso = Literal('[').suppress() closeiso = Literal(']').suppress() isotope = Optional(~White()+openiso+Regex("[1-9][0-9]*")+closeiso, default='0') isotope = isotope.setParseAction(lambda s,l,t: int(t[0]) if t[0] else 0) # Translate ion openion = Literal('{').suppress() closeion = Literal('}').suppress() ion = Optional(~White() +openion +Regex("([1-9][0-9]*)?[+-]") +closeion, default='0+') ion = ion.setParseAction(lambda s,l,t: int(t[0][-1]+(t[0][:-1] if len(t[0])>1 else '1'))) # Translate counts fract = Regex("(0|[1-9][0-9]*|)([.][0-9]*)") fract = fract.setParseAction(lambda s,l,t: float(t[0]) if t[0] else 1) whole = Regex("[1-9][0-9]*") whole = whole.setParseAction(lambda s,l,t: int(t[0]) if t[0] else 1) count = Optional(~White()+(fract|whole),default=1) # Convert symbol,isotope,ion,count to (count,isotope) element = symbol+isotope+ion+count def convert_element(string,location,tokens): #print "convert_element received",tokens symbol,isotope,ion,count = tokens[0:4] if isotope != 0: symbol = symbol[isotope] if ion != 0: symbol = symbol.ion[ion] return (count,symbol) element = element.setParseAction(convert_element) # Convert "count elements" to a pair implicit_group = count+OneOrMore(element) def convert_implicit(string,location,tokens): #print "implicit",tokens count = tokens[0] fragment = tokens[1:] return fragment if count==1 else (count,fragment) implicit_group = implicit_group.setParseAction(convert_implicit) # Convert "(composite) count" to a pair opengrp = space + Literal('(').suppress() + space closegrp = space + Literal(')').suppress() + space explicit_group = opengrp + composite + closegrp + count def convert_explicit(string,location,tokens): #print "explicit",tokens count = tokens[-1] fragment = tokens[:-1] return fragment if count == 1 else (count,fragment) explicit_group = explicit_group.setParseAction(convert_explicit) # Build composite from a set of groups group = implicit_group | explicit_group implicit_separator = separator | space composite << group + ZeroOrMore(implicit_separator + group) density = Literal('@').suppress() + count + Optional(Regex("[ni]"),default='i') compound = composite + Optional(density,default=None) def convert_compound(string,location,tokens): #print "compound",tokens if tokens[-1] is None: return Formula(structure=_immutable(tokens[:-1])) elif tokens[-1] == 'n': return Formula(structure=_immutable(tokens[:-2]), natural_density=tokens[-2]) else: return Formula(structure=_immutable(tokens[:-2]), density=tokens[-2]) compound = compound.setParseAction(convert_compound) partsep = space + Literal('//').suppress() + space percent = Literal('%').suppress() weight_percent = Regex("%(w((eigh)?t)?|m(ass)?)").suppress() + space by_weight = count + weight_percent + mixture + ZeroOrMore(partsep+count+(weight_percent|percent)+mixture) + partsep + mixture def convert_by_weight(string,location,tokens): #print "by weight",tokens piece = tokens[1:-1:2] + [tokens[-1]] fract = [float(v) for v in tokens[:-1:2]] fract.append(100-sum(fract)) #print piece, fract if len(piece) != len(fract): raise ValueError("Missing base component of mixture") if fract[-1] < 0: raise ValueError("Formula percentages must sum to less than 100%") return _mix_by_weight_pairs(zip(piece,fract)) mixture_by_weight = by_weight.setParseAction(convert_by_weight) volume_percent = Regex("%v(ol(ume)?)?").suppress() + space by_volume = count + volume_percent + mixture + ZeroOrMore(partsep+count+(volume_percent|percent)+mixture) + partsep + mixture def convert_by_volume(string,location,tokens): #print "by volume",tokens piece = tokens[1:-1:2] + [tokens[-1]] fract = [float(v) for v in tokens[:-1:2]] fract.append(100-sum(fract)) #print piece, fract if len(piece) != len(fract): raise ValueError("Missing base component of mixture "+string) if fract[-1] < 0: raise ValueError("Formula percentages must sum to less than 100%") return _mix_by_volume_pairs(zip(piece,fract)) mixture_by_volume = by_volume.setParseAction(convert_by_volume) mixture << (compound | (opengrp + (mixture_by_weight | mixture_by_volume) + closegrp)) formula = compound | mixture_by_weight | mixture_by_volume grammar = Optional(formula, default=Formula()) + StringEnd() grammar.setName('Chemical Formula') return grammar
@attr.s(auto_attribs=True) class Record(object): type: str content: str def preprocess(text: str) -> str: """Delete the page headers and trailers and blank lines from the text.""" lines = text.splitlines() clean_lines = (l for l in lines if not re.match(r" *Page \d+ of \d+ *", l) and not l.startswith("file://") and l.strip()) return "\n".join(clean_lines) TYPES = [Literal("SALE"), Literal("VOIDED")] def header_line() -> ParserElement: header_single = (Literal("Type :") + Or(TYPES).setResultsName("type") + Literal("Trs# :") + Integer.setResultsName("trs")) header_split = (Literal("Type :") + Literal("Trs# :") + Or(TYPES).setResultsName("type") + Integer.setResultsName("trs")) return MatchFirst([header_single, header_split]) def date_line() -> ParserElement: date_single = (Literal("Date :") + Word("1234567890-").setResultsName("date") + Literal("Invoice# :") + Integer.setResultsName("invoice"))
debugToks("startBlock", s, l, t) symbol = t[0][0] d = {} addToTree(symbol, d) treestack.append(curtree) curtree = d def endBlock(s, l, t): global curtree, treestack debugToks("endBlock", s, l, t) curtree = treestack.pop() symbol = Word(alphas + '_', alphanums + '_') hexval = Combine(Literal('0x') + Word(nums + 'abcdefABCDEF')).setParseAction(convertHex) decval = Word(nums).setParseAction(convertDec) enumval = Word(alphas + '_', alphanums + '_').setParseAction(convertEnum) stringval = quotedString.setParseAction(convertStr) value = hexval | decval | quotedString | enumval assignment = Group(symbol + '=' + value).setParseAction(addAssignment) block = Forward() statement = assignment | block block << Group(symbol + '{').setParseAction(startBlock) + ZeroOrMore( statement) + Literal('}').setParseAction(endBlock) comment = cStyleComment | (Literal('//') + restOfLine) config = ZeroOrMore(statement).ignore(comment) def parseFile(s):
def parse_line(attribute, string): Grammar = Suppress(Keyword('mpc.{}'.format(attribute)) + Keyword('=')) + String('data') + Suppress(Literal(';') + Optional(Comments)) result, i, j = Grammar.scanString(string).next() return [int_else_float_except_string(s) for s in result['data'].asList()]
symbol = Word(alphanums, bodyChars=alphanums + "_", min=1) sign = Optional(oneOf("+ -")) integer = Combine(sign + Word(nums)).setParseAction(lambda t: int(t[0])) number = Combine( Word("+-" + nums, nums) + Optional("." + Optional(Word(nums))) + Optional(oneOf("e E") + Word("+-" + nums, nums))).setParseAction(lambda t: float(t[0])) LPAREN = Suppress("(") RPAREN = Suppress(")") LBRACE = Suppress("{") RBRACE = Suppress("}") LBRACKET = Suppress("[") RBRACKET = Suppress("]") END = Suppress(";") PLUS = Literal("+") MINUS = Literal("-") single = number ^ symbol | QuotedString('"') | QuotedString("'") tuple_ = Group(LPAREN + delimitedList(single) + RPAREN) subscript_domain = (LBRACE + Group(delimitedList(symbol)).setResultsName("subscripts") + RBRACE) data = single | tuple_ # should not match a single (tr) simple_data = Group( NotAny("(tr)") + data + ZeroOrMore(Optional(Suppress(",")) + data)) # the first element of a set data record cannot be 'dimen', or else # these would match set_def_stmts
def someOf(*argv): return OneOrMore(Or(argv)) alpha_cap_uni = u"АБВГДЃЕЖЗЅИЈКЛЉМНЊОПРСТЌУФХЦЧЏШ" alpha_lower_uni = u"абвгдѓежзѕијклљмнњопрстќуфхцчџшáèéѐôѝ" alpha_uni = alpha_lower_uni + alpha_cap_uni word = Word(alpha_uni) latin_word = Word(alphas) initial = Word(alpha_cap_uni, '.', exact=2) number = Word(nums) bullet = originalTextFor(number + Literal('.')) percent = originalTextFor(number + Literal('%')) hypen_word = Combine(word + Literal('-') + word) apos_word1 = Combine(Literal('\'') + word) apos_word2 = Combine(word + Literal('\'') + word) new_line = Literal('\n') tab = Literal('\t') punctuation = list(u"‘’.,;„“”()‘:\"\'`′!?-–—…") + ['...'] punkt = map(Literal, punctuation) all_ = [word, initial, bullet, hypen_word, apos_word1, apos_word2, \ number, percent, new_line, latin_word, tab] all_.extend(punkt) all_ = Or(all_).parseWithTabs()
Description: Provides managed-key-related grammar in PyParsing engine for ISC-configuration style """ from pyparsing import Word, alphanums, Group, Keyword, Literal, OneOrMore from bind9_parser.isc_utils import semicolon, lbrack, rbrack, number_type,\ squote, dquote, Combine, Char from bind9_parser.isc_rr import rr_domain_name_or_root managed_keyname_type = rr_domain_name_or_root managed_keyname_type.setName('keyname_base') managed_keyname_dquoted = Combine( Literal('"') - managed_keyname_type + Literal('"') ) # keyname_dquoted.setName('keyname_dquoted') managed_keyname_squoted = Combine( Literal("'") - managed_keyname_type + Literal("'") )('key_id') # keyname_dquoted.setName('keyname_squoted') managed_key_domain_name = ( managed_keyname_dquoted | managed_keyname_squoted
# URL extractor # Copyright 2004, Paul McGuire from pyparsing import Literal,Suppress,CharsNotIn,CaselessLiteral,\ Word,dblQuotedString,alphanums,SkipTo import urllib.request, urllib.parse, urllib.error import pprint # Define the pyparsing grammar for a URL, that is: # URLlink ::= <a href= URL>linkText</a> # URL ::= doubleQuotedString | alphanumericWordPath # Note that whitespace may appear just about anywhere in the link. Note also # that it is not necessary to explicitly show this in the pyparsing grammar; by default, # pyparsing skips over whitespace between tokens. linkOpenTag = (Literal("<") + "a" + "href" + "=").suppress() + \ ( dblQuotedString | Word(alphanums+"/") ) + \ Suppress(">") linkCloseTag = Literal("<") + "/" + CaselessLiteral("a") + ">" link = linkOpenTag + SkipTo(linkCloseTag) + linkCloseTag.suppress() # Go get some HTML with some links in it. serverListPage = urllib.request.urlopen( "http://www.yahoo.com" ) htmlText = serverListPage.read() serverListPage.close() # scanString is a generator that loops through the input htmlText, and for each # match yields the tokens and start and end locations (for this application, we are # not interested in the start and end values). for toks,strt,end in link.scanString(htmlText): print(toks.asList()) # Rerun scanString, but this time create a dict of text:URL key-value pairs.
def parse_query_string(self, query_string): """ Function that parse the querystring, extracting infos for limit, offset, ordering, filters, attribute and extra projections. :param query_string (as obtained from request.query_string) :return: parsed values for the querykeys """ from pyparsing import Word, alphas, nums, alphanums, printables, \ ZeroOrMore, OneOrMore, Suppress, Optional, Literal, Group, \ QuotedString, Combine, \ StringStart as SS, StringEnd as SE, \ WordEnd as WE, \ ParseException from pyparsing import pyparsing_common as ppc from dateutil import parser as dtparser from psycopg2.tz import FixedOffsetTimezone ## Define grammar # key types key = Word(alphas + '_', alphanums + '_') # operators operator = (Literal('=like=') | Literal('=ilike=') | Literal('=in=') | Literal('=notin=') | Literal('=') | Literal('!=') | Literal('>=') | Literal('>') | Literal('<=') | Literal('<')) # Value types valueNum = ppc.number valueBool = ( Literal('true') | Literal('false')).addParseAction(lambda toks: bool(toks[0])) valueString = QuotedString('"', escQuote='""') valueOrderby = Combine(Optional(Word('+-', exact=1)) + key) ## DateTimeShift value. First, compose the atomic values and then # combine # them and convert them to datetime objects # Date valueDate = Combine( Word(nums, exact=4) + Literal('-') + Word(nums, exact=2) + Literal('-') + Word(nums, exact=2)) # Time valueTime = Combine( Literal('T') + Word(nums, exact=2) + Optional(Literal(':') + Word(nums, exact=2)) + Optional(Literal(':') + Word(nums, exact=2))) # Shift valueShift = Combine( Word('+-', exact=1) + Word(nums, exact=2) + Optional(Literal(':') + Word(nums, exact=2))) # Combine atomic values valueDateTime = Combine( valueDate + Optional(valueTime) + Optional(valueShift) + WE(printables.translate(None, '&')) # To us the # word must end with '&' or end of the string # Adding WordEnd only here is very important. This makes atomic # values for date, time and shift not really # usable alone individually. ) ############################################################################ # Function to convert datetime string into datetime object. The # format is # compliant with ParseAction requirements def validate_time(s, loc, toks): datetime_string = toks[0] # Check the precision precision = len(datetime_string.replace('T', ':').split(':')) # Parse try: dt = dtparser.parse(datetime_string) except ValueError: raise RestInputValidationError( "time value has wrong format. The " "right format is " "<date>T<time><offset>, " "where <date> is expressed as " "[YYYY]-[MM]-[DD], " "<time> is expressed as [HH]:[MM]:[" "SS], " "<offset> is expressed as +/-[HH]:[" "MM] " "given with " "respect to UTC") if dt.tzinfo is not None: tzoffset_minutes = int( dt.tzinfo.utcoffset(None).total_seconds() / 60) return datetime_precision( dt.replace(tzinfo=FixedOffsetTimezone( offset=tzoffset_minutes, name=None)), precision) else: return datetime_precision( dt.replace( tzinfo=FixedOffsetTimezone(offset=0, name=None)), precision) ######################################################################## # Convert datetime value to datetime object valueDateTime.setParseAction(validate_time) # More General types value = (valueString | valueBool | valueDateTime | valueNum | valueOrderby) # List of values (I do not check the homogeneity of the types of values, # query builder will do it somehow) valueList = Group(value + OneOrMore(Suppress(',') + value) + Optional(Suppress(','))) # Fields singleField = Group(key + operator + value) listField = Group(key + (Literal('=in=') | Literal('=notin=')) + valueList) orderbyField = Group(key + Literal('=') + valueList) Field = (listField | orderbyField | singleField) # Fields separator separator = Suppress(Literal('&')) # General query string generalGrammar = SS() + Optional(Field) + ZeroOrMore( separator + Field) + \ Optional(separator) + SE() ## Parse the query string try: fields = generalGrammar.parseString(query_string) # JQuery adds _=timestamp a parameter to not use cached data/response. # To handle query, remove this "_" parameter from the query string # For more details check issue #789 # (https://github.com/aiidateam/aiida_core/issues/789) in aiida_core field_list = [ entry for entry in fields.asList() if entry[0] != "_" ] except ParseException as e: raise RestInputValidationError( "The query string format is invalid. " "Parser returned this massage: \"{" "}.\" Please notice that the column " "number " "is counted from " "the first character of the query " "string.".format(e)) ## return the translator instructions elaborated from the field_list return self.build_translator_parameters(field_list)
See the License for the specific language governing permissions and limitations under the License. #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=# """ import logging import re from pyparsing import Word, alphas, alphanums, ZeroOrMore, Literal, ParseException, Forward from agora_wot.blocks.operators import lslug, objectValue, filterObjects __author__ = 'Fernando Serena' log = logging.getLogger('agora.wot') lparen = Literal("(") rparen = Literal(")") identifier = Word(alphas) functor = identifier symbols = """!"#%&'*+,-./:;<=>?@[\]^_`|~""" arg_chars = alphanums + symbols # allow expression to be used recursively expression = Forward() arg = expression | Word(arg_chars) args = arg + ZeroOrMore("," + arg) expression << functor + lparen + args + rparen
hex literal long: #fafafa rgb bytes: rgb(255,100,0) rgb percent: rgb(100%,100%,0%) named color: black """ import wx import string import urlparse from pyparsing import nums, Literal, Optional, oneOf, Group, StringEnd, Combine, Word, alphas, hexnums from ..pathdata import number, sign number = number.copy() integerConstant = Word(nums+"+-").setParseAction(lambda t:int(t[0])) #rgb format parser comma = Literal(",").suppress() def clampColourByte(val): val = int(val) return min(max(0,val), 255) def clampColourPerc(val): val = float(val) return min(max(0,val), 100) def parseColorPerc(token): val = token[0] val = clampColourPerc(val) #normalize to bytes return int(255 * (val / 100.0))
def __init__(self): """ expop :: '^' multop :: '*' | '/' addop :: '+' | '-' integer :: ['+' | '-'] '0'..'9'+ atom :: PI | E | real | fn '(' expr ')' | '(' expr ')' factor :: atom [ expop factor ]* term :: factor [ multop factor ]* expr :: term [ addop term ]* """ point = Literal(".") e = CaselessLiteral("E") fnumber = Combine( Word("+-" + nums, nums) + Optional(point + Optional(Word(nums))) + Optional(e + Word("+-" + nums, nums))) ident = Word(alphas, alphas + nums + "_$") plus = Literal("+") minus = Literal("-") mult = Literal("*") div = Literal("/") lpar = Literal("(").suppress() rpar = Literal(")").suppress() addop = plus | minus multop = mult | div expop = Literal("^") pi = CaselessLiteral("PI") expr = Forward() atom = ((Optional(oneOf("- +")) + (pi | e | fnumber | ident + lpar + expr + rpar).setParseAction(self.pushFirst)) | Optional(oneOf("- +")) + Group(lpar + expr + rpar)).setParseAction(self.pushUMinus) # by defining exponentiation as "atom [ ^ factor ]..." instead of # "atom [ ^ atom ]...", we get right-to-left exponents, instead of left-to-right # that is, 2^3^2 = 2^(3^2), not (2^3)^2. factor = Forward() factor << atom + ZeroOrMore( (expop + factor).setParseAction(self.pushFirst)) term = factor + ZeroOrMore( (multop + factor).setParseAction(self.pushFirst)) expr << term + ZeroOrMore( (addop + term).setParseAction(self.pushFirst)) # addop_term = ( addop + term ).setParseAction( self.pushFirst ) # general_term = term + ZeroOrMore( addop_term ) | OneOrMore( addop_term) # expr << general_term self.bnf = expr # map operator symbols to corresponding arithmetic operations epsilon = 1e-12 self.opn = { "+": operator.add, "-": operator.sub, "*": operator.mul, "/": operator.truediv, "^": operator.pow, "==": operator.eq } self.fn = { "sin": math.sin, "cos": math.cos, "tan": math.tan, "abs": abs, "trunc": lambda a: int(a), "round": round, "sgn": lambda a: abs(a) > epsilon and cmp(a, 0) or 0 }
with all the configuration file needed for the execution of the inference engine (See user guide documentation for more information). (learn_rules) - runs a machine learning algorithm on a specified dataset (in ARFF format) in order to learn some other rules (reset) - removes all the data loaded so far (exit) - closes the interpreter's session ---------------------------------------------------------------- ''' print(command_list_help) valid_command = Literal('load') | Literal('facts') | Literal('rules') | \ Literal('help') | Literal('exit') | Literal('learn_rules') | Literal('run') |\ Literal('reset') | Literal('step') banner = ''' ---------------------------------------------------------------- ### YAIEP - Yet Another Inference Engine in Python ### ---------------------------------------------------------------- ''' _command_list_interpreter = { 'load': _do_load, 'facts': _do_facts, 'rules': _do_rules, 'learn_rules': _do_learn, 'help': _do_help,
Word, Literal, White, Optional, dictOf, srange, alphanums, nums, printables, restOfLine, lineEnd, ) # some constants SPACE = Suppress(White(ws=' ', min=1, max=1)) DASH = Literal('-') PLUS = Literal('+') COLON = Literal(':') LESS_THAN = Literal('<') GREATER_THAN = Literal('>') PERIOD = Literal('.') TEE = Literal('T') UNDERSCORE = Literal('_') STRIP_QUOTES = Optional(Suppress(Word('"\''))) # convert values to integers def toInt(s, loc, toks): return int(toks[0]) # pri - '<40>'
import os from builtins import open import logging import numpy as np from pyparsing import Word, nums, alphanums, LineEnd, Suppress, Literal, restOfLine, OneOrMore, Optional, Keyword, Group, printables from ...utils import int_else_float_except_string logger = logging.getLogger(__file__) Float = Word(nums + '.' + '-' + '+' + 'e') Name = Word(alphanums) String = Optional(Suppress("'")) + Word(printables, alphanums) + Optional(Suppress("'")) NL = LineEnd() Comments = Suppress(Literal('%')) + restOfLine def parse_file(attribute, string): if attribute in ['gen', 'gencost', 'bus', 'branch'] and attribute in string: return parse_table(attribute, string) elif attribute in ['version', 'baseMVA'] and attribute in string: return parse_line(attribute, string) else: logger.debug("Unable to parse mpc.%s. Please check the input file or contact the developer.", attribute) return None def parse_line(attribute, string): Grammar = Suppress(Keyword('mpc.{}'.format(attribute)) + Keyword('=')) + String('data') + Suppress(Literal(';') + Optional(Comments))
def property_grammar(): ParserElement.setDefaultWhitespaceChars(' ') dpi_setting = (Optional('*')('DEFAULT') + INTEGER('DPI') + Suppress('@') + INTEGER('HZ'))('SETTINGS*') mount_matrix_row = SIGNED_REAL + ',' + SIGNED_REAL + ',' + SIGNED_REAL mount_matrix = (mount_matrix_row + ';' + mount_matrix_row + ';' + mount_matrix_row)('MOUNT_MATRIX') xkb_setting = Optional(Word(alphanums + '+-/@._')) props = (('MOUSE_DPI', Group(OneOrMore(dpi_setting))), ('MOUSE_WHEEL_CLICK_ANGLE', INTEGER), ('MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL', INTEGER), ('MOUSE_WHEEL_CLICK_COUNT', INTEGER), ('MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL', INTEGER), ('ID_AUTOSUSPEND', Literal('1')), ('ID_INPUT', Literal('1')), ('ID_INPUT_ACCELEROMETER', Literal('1')), ('ID_INPUT_JOYSTICK', Literal('1')), ('ID_INPUT_KEY', Literal('1')), ('ID_INPUT_KEYBOARD', Literal('1')), ('ID_INPUT_MOUSE', Literal('1')), ('ID_INPUT_POINTINGSTICK', Literal('1')), ('ID_INPUT_SWITCH', Literal('1')), ('ID_INPUT_TABLET', Literal('1')), ('ID_INPUT_TABLET_PAD', Literal('1')), ('ID_INPUT_TOUCHPAD', Literal('1')), ('ID_INPUT_TOUCHSCREEN', Literal('1')), ('ID_INPUT_TRACKBALL', Literal('1')), ('POINTINGSTICK_SENSITIVITY', INTEGER), ('POINTINGSTICK_CONST_ACCEL', REAL), ('ID_INPUT_JOYSTICK_INTEGRATION', Or(('internal', 'external'))), ('ID_INPUT_TOUCHPAD_INTEGRATION', Or(('internal', 'external'))), ('XKB_FIXED_LAYOUT', xkb_setting), ('XKB_FIXED_VARIANT', xkb_setting), ('XKB_FIXED_MODEL', xkb_setting), ('KEYBOARD_LED_NUMLOCK', Literal('0')), ('KEYBOARD_LED_CAPSLOCK', Literal('0')), ('ACCEL_MOUNT_MATRIX', mount_matrix), ('ACCEL_LOCATION', Or(('display', 'base'))), ('PROXIMITY_NEAR_LEVEL', INTEGER), ) fixed_props = [Literal(name)('NAME') - Suppress('=') - val('VALUE') for name, val in props] kbd_props = [Regex(r'KEYBOARD_KEY_[0-9a-f]+')('NAME') - Suppress('=') - ('!' ^ (Optional('!') - Word(alphanums + '_')))('VALUE') ] abs_props = [Regex(r'EVDEV_ABS_[0-9a-f]{2}')('NAME') - Suppress('=') - Word(nums + ':')('VALUE') ] grammar = Or(fixed_props + kbd_props + abs_props) + EOL return grammar
def formula_grammar(table): """ Construct a parser for molecular formulas. :Parameters: *table* = None : PeriodicTable If table is specified, then elements and their associated fields will be chosen from that periodic table rather than the default. :Returns: *parser* : pyparsing.ParserElement. The ``parser.parseString()`` method returns a list of pairs (*count,fragment*), where fragment is an *isotope*, an *element* or a list of pairs (*count,fragment*). """ # Recursive formula = Forward() # Lookup the element in the element table symbol = Regex("[A-Z][a-z]*") symbol = symbol.setParseAction(lambda s,l,t: table.symbol(t[0])) # Translate isotope openiso = Literal('[').suppress() closeiso = Literal(']').suppress() isotope = Optional(~White()+openiso+Regex("[1-9][0-9]*")+closeiso, default='0') isotope = isotope.setParseAction(lambda s,l,t: int(t[0]) if t[0] else 0) # Translate counts fract = Regex("(0|[1-9][0-9]*|)([.][0-9]*)") fract = fract.setParseAction(lambda s,l,t: float(t[0]) if t[0] else 1) whole = Regex("[1-9][0-9]*") whole = whole.setParseAction(lambda s,l,t: int(t[0]) if t[0] else 1) count = Optional(~White()+(fract|whole),default=1) # Convert symbol,isotope,count to (count,isotope) element = symbol+isotope+count def convert_element(string,location,tokens): #print "convert_element received",tokens symbol,isotope,count = tokens[0:3] if isotope != 0: symbol = symbol[isotope] return (count,symbol) element = element.setParseAction(convert_element) # Convert "count elements" to a pair implicit_group = count+OneOrMore(element) def convert_implicit(string,location,tokens): #print "convert_implicit received",tokens count = tokens[0] fragment = tokens[1:] return fragment if count==1 else (count,fragment) implicit_group = implicit_group.setParseAction(convert_implicit) # Convert "(formula) count" to a pair opengrp = Literal('(').suppress() closegrp = Literal(')').suppress() explicit_group = opengrp + formula + closegrp + count def convert_explicit(string,location,tokens): #print "convert_group received",tokens count = tokens[-1] fragment = tokens[:-1] return fragment if count == 1 else (count,fragment) explicit_group = explicit_group.setParseAction(convert_explicit) group = implicit_group | explicit_group separator = Optional(Literal('+').suppress()) + Optional(White().suppress()) formula << group + ZeroOrMore(Optional(White().suppress())+separator+group) grammar = Optional(formula) + StringEnd() grammar.setName('Chemical Formula') return grammar
_PROCEDURE = CaselessKeyword("PROCEDURE") _TABLE = CaselessKeyword("TABLE") _INTO = CaselessKeyword("INTO") _FROM = CaselessKeyword("FROM") _ENUM = CaselessKeyword("ENUM") _SET = CaselessKeyword("SET") _SELECT = CaselessKeyword("SELECT").setResultsName("command") _DELETE = CaselessKeyword("DELETE").setResultsName("command") _INSERT = CaselessKeyword("INSERT").setResultsName("command") _UPDATE = CaselessKeyword("UPDATE").setResultsName("command") IF_NOT_EXISTS = Group("IF") + CaselessKeyword("NOT") + CaselessKeyword( "EXISTS") _THROW = _sql_identifier(Keyword("__throw")) _RETURNS = CaselessKeyword("returns") _SQL_EOL = Literal(";") _ID = Word(alphanums + "_.").setResultsName("name") _ID_LIST = delimitedList(_ID, combine=False) _VALUE = (Combine(_ID + Literal("(") + SkipTo(")", include=True)) | Word(alphanums + "$!#%&*+-./:<=>?@[\]^_~`") | quotedString).setResultsName("value") _VALUE_LIST = delimitedList(_VALUE, combine=False) _SQL_DIRECTION = oneOf('INOUT IN OUT', caseless=True) _SQL_TYPE = Combine( Word(alphanums + '_') + Optional('(' + delimitedList(Word(nums + ' '), combine=True) + ')')) _SQL_ID = _sql_identifier(_ID) _SQL_ID_LIST = delimitedList(_SQL_ID, combine=False) _SKIP_TO_END = SkipTo(_SQL_EOL)
"name": "Base spanish date with month name and articles and lowcase", "pattern": Word(nums, min=1, max=2).setResultsName("day") + CaselessLiteral("de").suppress() + BASE_PATTERNS_ES["pat:es:months_lc"].setResultsName("month") + CaselessLiteral("de").suppress() + Word(nums, exact=4).setResultsName("year"), "length": {"min": 11, "max": 26}, "format": "%d %m %Y", "filter": 1, }, { "key": "dt:date:es_rare_1", "name": "Spanish date stars with month name", "pattern": BASE_PATTERNS_ES["pat:es:months"].setResultsName("month") + Word(nums, min=1, max=2).setResultsName("day") + Literal(",").suppress() + Word(nums, exact=4).setResultsName("year"), "length": {"min": 11, "max": 25}, "format": "%M %d %Y", "filter": 1, }, { "key": "dt:date:es_rare_2", "name": "Spanish date stars with month name lowcase", "pattern": BASE_PATTERNS_ES["pat:es:months_lc"].setResultsName("month") + Word(nums, min=1, max=2).setResultsName("day") + Literal(",").suppress() + Word(nums, exact=4).setResultsName("year"), "length": {"min": 11, "max": 25}, "format": "%M %d %Y", "filter": 1,
def _macros(expr): return lineStart + Suppress(Literal("#")) + expr
def parse(cls, content, basedir=None, resolve=True, unresolved_value=DEFAULT_SUBSTITUTION): """parse a HOCON content :param content: HOCON content to parse :type content: basestring :param resolve: if true, resolve substitutions :type resolve: boolean :param unresolved_value: assigned value value to unresolved substitution. If overriden with a default value, it will replace all unresolved value to the default value. If it is set to to pyhocon.STR_SUBSTITUTION then it will replace the value by its substitution expression (e.g., ${x}) :type unresolved_value: boolean :return: a ConfigTree or a list """ unescape_pattern = re.compile(r'\\.') def replace_escape_sequence(match): value = match.group(0) return cls.REPLACEMENTS.get(value, value) def norm_string(value): return unescape_pattern.sub(replace_escape_sequence, value) def unescape_string(tokens): return ConfigUnquotedString(norm_string(tokens[0])) def parse_multi_string(tokens): # remove the first and last 3 " return tokens[0][3:-3] def convert_number(tokens): n = tokens[0] try: return int(n, 10) except ValueError: return float(n) def safe_convert_number(tokens): n = tokens[0] try: return int(n, 10) except ValueError: try: return float(n) except ValueError: return n def convert_period(tokens): period_value = int(tokens.value) period_identifier = tokens.unit period_unit = next((single_unit for single_unit, values in cls.get_supported_period_type_map().items() if period_identifier in values)) return period(period_value, period_unit) # ${path} or ${?path} for optional substitution SUBSTITUTION_PATTERN = r"\$\{(?P<optional>\?)?(?P<variable>[^}]+)\}(?P<ws>[ \t]*)" def create_substitution(instring, loc, token): # remove the ${ and } match = re.match(SUBSTITUTION_PATTERN, token[0]) variable = match.group('variable') ws = match.group('ws') optional = match.group('optional') == '?' substitution = ConfigSubstitution(variable, optional, ws, instring, loc) return substitution # ${path} or ${?path} for optional substitution STRING_PATTERN = '"(?P<value>(?:[^"\\\\]|\\\\.)*)"(?P<ws>[ \t]*)' def create_quoted_string(instring, loc, token): # remove the ${ and } match = re.match(STRING_PATTERN, token[0]) value = norm_string(match.group('value')) ws = match.group('ws') return ConfigQuotedString(value, ws, instring, loc) def include_config(instring, loc, token): url = None file = None required = False if token[0] == 'required': required = True final_tokens = token[1:] else: final_tokens = token if len(final_tokens) == 1: # include "test" value = final_tokens[0].value if isinstance( final_tokens[0], ConfigQuotedString) else final_tokens[0] if value.startswith("http://") or value.startswith( "https://") or value.startswith("file://"): url = value else: file = value elif len(final_tokens) == 2: # include url("test") or file("test") value = final_tokens[1].value if isinstance( token[1], ConfigQuotedString) else final_tokens[1] if final_tokens[0] == 'url': url = value else: file = value if url is not None: logger.debug('Loading config from url %s', url) obj = ConfigFactory.parse_URL(url, resolve=False, required=required, unresolved_value=NO_SUBSTITUTION) elif file is not None: path = file if basedir is None else os.path.join(basedir, file) logger.debug('Loading config from file %s', path) obj = ConfigFactory.parse_file( path, resolve=False, required=required, unresolved_value=NO_SUBSTITUTION) else: raise ConfigException( 'No file or URL specified at: {loc}: {instring}', loc=loc, instring=instring) return ConfigInclude(obj if isinstance(obj, list) else obj.items()) @contextlib.contextmanager def set_default_white_spaces(): default = ParserElement.DEFAULT_WHITE_CHARS ParserElement.setDefaultWhitespaceChars(' \t') yield ParserElement.setDefaultWhitespaceChars(default) with set_default_white_spaces(): assign_expr = Forward() true_expr = Keyword("true", caseless=True).setParseAction( replaceWith(True)) false_expr = Keyword("false", caseless=True).setParseAction( replaceWith(False)) null_expr = Keyword("null", caseless=True).setParseAction( replaceWith(NoneValue())) # key = QuotedString('"', escChar='\\', unquoteResults=False) | Word(alphanums + alphas8bit + '._- /') regexp_numbers = r'[+-]?(\d*\.\d+|\d+(\.\d+)?)([eE][+\-]?\d+)?(?=$|[ \t]*([\$\}\],#\n\r]|//))' key = QuotedString('"', escChar='\\', unquoteResults=False) | \ Regex(regexp_numbers, re.DOTALL).setParseAction(safe_convert_number) | \ Word(alphanums + alphas8bit + '._- /') eol = Word('\n\r').suppress() eol_comma = Word('\n\r,').suppress() comment = (Literal('#') | Literal('//')) - SkipTo(eol | StringEnd()) comment_eol = Suppress(Optional(eol_comma) + comment) comment_no_comma_eol = (comment | eol).suppress() number_expr = Regex(regexp_numbers, re.DOTALL).setParseAction(convert_number) period_types = itertools.chain.from_iterable( cls.get_supported_period_type_map().values()) period_expr = Regex(r'(?P<value>\d+)\s*(?P<unit>' + '|'.join(period_types) + ')$').setParseAction(convert_period) # multi line string using """ # Using fix described in http://pyparsing.wikispaces.com/share/view/3778969 multiline_string = Regex( '""".*?"*"""', re.DOTALL | re.UNICODE).setParseAction(parse_multi_string) # single quoted line string quoted_string = Regex( r'"(?:[^"\\\n]|\\.)*"[ \t]*', re.UNICODE).setParseAction(create_quoted_string) # unquoted string that takes the rest of the line until an optional comment # we support .properties multiline support which is like this: # line1 \ # line2 \ # so a backslash precedes the \n unquoted_string = Regex( r'(?:[^^`+?!@*&"\[\{\s\]\}#,=\$\\]|\\.)+[ \t]*', re.UNICODE).setParseAction(unescape_string) substitution_expr = Regex(r'[ \t]*\$\{[^\}]+\}[ \t]*' ).setParseAction(create_substitution) string_expr = multiline_string | quoted_string | unquoted_string value_expr = period_expr | number_expr | true_expr | false_expr | null_expr | string_expr include_content = (quoted_string | ( (Keyword('url') | Keyword('file')) - Literal('(').suppress() - quoted_string - Literal(')').suppress())) include_expr = (Keyword("include", caseless=True).suppress() + (include_content | (Keyword("required") - Literal('(').suppress() - include_content - Literal(')').suppress())) ).setParseAction(include_config) root_dict_expr = Forward() dict_expr = Forward() list_expr = Forward() multi_value_expr = ZeroOrMore(comment_eol | include_expr | substitution_expr | dict_expr | list_expr | value_expr | (Literal('\\') - eol).suppress()) # for a dictionary : or = is optional # last zeroOrMore is because we can have t = {a:4} {b: 6} {c: 7} which is dictionary concatenation inside_dict_expr = ConfigTreeParser( ZeroOrMore(comment_eol | include_expr | assign_expr | eol_comma)) inside_root_dict_expr = ConfigTreeParser( ZeroOrMore(comment_eol | include_expr | assign_expr | eol_comma), root=True) dict_expr << Suppress('{') - inside_dict_expr - Suppress('}') root_dict_expr << Suppress('{') - inside_root_dict_expr - Suppress( '}') list_entry = ConcatenatedValueParser(multi_value_expr) list_expr << Suppress('[') - ListParser(list_entry - ZeroOrMore( eol_comma - list_entry)) - Suppress(']') # special case when we have a value assignment where the string can potentially be the remainder of the line assign_expr << Group(key - ZeroOrMore(comment_no_comma_eol) - ( dict_expr | (Literal('=') | Literal(':') | Literal('+=')) - ZeroOrMore(comment_no_comma_eol) - ConcatenatedValueParser(multi_value_expr))) # the file can be { ... } where {} can be omitted or [] config_expr = ZeroOrMore(comment_eol | eol) + ( list_expr | root_dict_expr | inside_root_dict_expr) + ZeroOrMore(comment_eol | eol_comma) config = config_expr.parseString(content, parseAll=True)[0] if resolve: allow_unresolved = resolve and unresolved_value is not DEFAULT_SUBSTITUTION and unresolved_value is not MANDATORY_SUBSTITUTION has_unresolved = cls.resolve_substitutions( config, allow_unresolved) if has_unresolved and unresolved_value is MANDATORY_SUBSTITUTION: raise ConfigSubstitutionException( 'resolve cannot be set to True and unresolved_value to MANDATORY_SUBSTITUTION' ) if unresolved_value is not NO_SUBSTITUTION and unresolved_value is not DEFAULT_SUBSTITUTION: cls.unresolve_substitutions_to_value(config, unresolved_value) return config
def _sql_comment(expr): return lineStart + Suppress(Literal("-- ")) + expr
def parse_algebra(self): """ Parse an algebraic expression into a tree. Store a `pyparsing.ParseResult` in `self.tree` with proper groupings to reflect parenthesis and order of operations. Leave all operators in the tree and do not parse any strings of numbers into their float versions. Adding the groups and result names makes the `repr()` of the result really gross. For debugging, use something like print OBJ.tree.asXML() """ # 0.33 or 7 or .34 or 16. number_part = Word(nums) inner_number = (number_part + Optional("." + Optional(number_part))) | ("." + number_part) # pyparsing allows spaces between tokens--`Combine` prevents that. inner_number = Combine(inner_number) # SI suffixes and percent. number_suffix = MatchFirst(Literal(k) for k in SUFFIXES.keys()) # 0.33k or 17 plus_minus = Literal('+') | Literal('-') number = Group( Optional(plus_minus) + inner_number + Optional( CaselessLiteral("E") + Optional(plus_minus) + number_part) + Optional(number_suffix)) number = number("number") # Predefine recursive variables. expr = Forward() # Handle variables passed in. They must start with a letter # and may contain numbers and underscores afterward. inner_varname = Combine( Word(alphas, alphanums + "_") + ZeroOrMore("'")) # Alternative variable name in tensor format # Tensor name must start with a letter, continue with alphanums # Indices may be alphanumeric # e.g., U_{ijk}^{123} upper_indices = Literal("^{") + Word(alphanums) + Literal("}") lower_indices = Literal("_{") + Word(alphanums) + Literal("}") tensor_lower = Combine( Word(alphas, alphanums) + lower_indices + ZeroOrMore("'")) tensor_mixed = Combine( Word(alphas, alphanums) + Optional(lower_indices) + upper_indices + ZeroOrMore("'")) # Test for mixed tensor first, then lower tensor alone, then generic variable name varname = Group(tensor_mixed | tensor_lower | inner_varname)("variable") varname.setParseAction(self.variable_parse_action) # Same thing for functions. function = Group(inner_varname + Suppress("(") + expr + Suppress(")"))("function") function.setParseAction(self.function_parse_action) atom = number | function | varname | "(" + expr + ")" atom = Group(atom)("atom") # Do the following in the correct order to preserve order of operation. pow_term = atom + ZeroOrMore("^" + atom) pow_term = Group(pow_term)("power") par_term = pow_term + ZeroOrMore('||' + pow_term) # 5k || 4k par_term = Group(par_term)("parallel") prod_term = par_term + ZeroOrMore( (Literal('*') | Literal('/')) + par_term) # 7 * 5 / 4 prod_term = Group(prod_term)("product") sum_term = Optional(plus_minus) + prod_term + ZeroOrMore( plus_minus + prod_term) # -5 + 4 - 3 sum_term = Group(sum_term)("sum") # Finish the recursion. expr << sum_term # pylint: disable=pointless-statement self.tree = (expr + stringEnd).parseString(self.math_expr)[0]
def _select_hint(expr): return Suppress(Literal("-- >")) + expr
logger.debug('finger_confs: %s' % list(finger_confs.items())) fingers = [] for indices, properties in finger_confs.items(): index_list = indices if len(indices) == 0: index_list = list(FingerIndex) for i in index_list: f = Finger(i, properties) fingers.append(f) logger.debug('Parsed Fingers: %s' % fingers) return fingers which_hand = (Optional(Literal('N')) + Literal('D')).setParseAction(convert_dominant)('dominant') start_end = (Literal('s') | Literal('e')).setParseAction(convert_start)('start_pos') orient = Word('iofbud', exact=1).setParseAction(convert_orient) finger_index = Word('01234', exact=1)('f_index').setParseAction(convert_index) finger_property = Word('-+xstcrb', exact=1)('f_prop').setParseAction(convert_finger_prop) palm = (which_hand('dominant') + Optional(start_end) + orient('palm_dir') + orient('finger_dir'))('palm').setParseAction(create_palm) finger_props = OneOrMore(finger_property) finger_indices = OneOrMore(finger_index)
def get_fragment_grammar(sdkconfig, fragment_file): # Match header [mapping] header = Suppress('[') + Suppress('mapping') + Suppress(']') # There are three possible patterns for mapping entries: # obj:symbol (scheme) # obj (scheme) # * (scheme) obj = Fragment.ENTITY.setResultsName('object') symbol = Suppress(':') + Fragment.IDENTIFIER.setResultsName('symbol') scheme = Suppress('(') + Fragment.IDENTIFIER.setResultsName( 'scheme') + Suppress(')') pattern1 = Group(obj + symbol + scheme) pattern2 = Group(obj + scheme) pattern3 = Group(Literal(Entity.ALL).setResultsName('object') + scheme) mapping_entry = pattern1 | pattern2 | pattern3 # To simplify parsing, classify groups of condition-mapping entry into two types: normal and default # A normal grouping is one with a non-default condition. The default grouping is one which contains the # default condition mapping_entries = Group( ZeroOrMore(mapping_entry)).setResultsName('mappings') normal_condition = Suppress(':') + originalTextFor( SDKConfig.get_expression_grammar()) default_condition = Optional( Suppress(':') + Literal(DeprecatedMapping.DEFAULT_CONDITION)) normal_group = Group( normal_condition.setResultsName('condition') + mapping_entries) default_group = Group(default_condition + mapping_entries).setResultsName('default_group') normal_groups = Group( ZeroOrMore(normal_group)).setResultsName('normal_groups') # Any mapping fragment definition can have zero or more normal group and only one default group as a last entry. archive = Suppress('archive') + Suppress( ':') + Fragment.ENTITY.setResultsName('archive') entries = Suppress('entries') + Suppress(':') + ( normal_groups + default_group).setResultsName('entries') mapping = Group(header + archive + entries) mapping.ignore('#' + restOfLine) def parsed_deprecated_mapping(pstr, loc, toks): fragment = Mapping() fragment.archive = toks[0].archive fragment.name = re.sub(r'[^0-9a-zA-Z]+', '_', fragment.archive) fragment.deprecated = True fragment.entries = set() condition_true = False for entries in toks[0].entries[0]: condition = next(iter(entries.condition.asList())).strip() condition_val = sdkconfig.evaluate_expression(condition) if condition_val: for entry in entries[1]: fragment.entries.add( (entry.object, None if entry.symbol == '' else entry.symbol, entry.scheme)) condition_true = True break if not fragment.entries and not condition_true: try: entries = toks[0].entries[1][1] except IndexError: entries = toks[0].entries[1][0] for entry in entries: fragment.entries.add( (entry.object, None if entry.symbol == '' else entry.symbol, entry.scheme)) if not fragment.entries: fragment.entries.add(('*', None, 'default')) dep_warning = str( ParseFatalException( pstr, loc, 'Warning: Deprecated old-style mapping fragment parsed in file %s.' % fragment_file)) print(dep_warning) return fragment mapping.setParseAction(parsed_deprecated_mapping) return mapping
from pyparsing import ZeroOrMore, OneOrMore, Optional, Literal, Word, alphas, nums ''' Created on 31 aug. 2013 Pyparsing grammar describing the trade section of EU4 save files @author: Jeroen Kools ''' # Terminals eq = Literal("=").suppress() begin = Literal("{").suppress() stop = Literal("}").suppress() quote = Literal('"').suppress() name = Word(alphas, alphas + nums + "_") quotedName = quote + name + quote yesno = Literal("yes") | Literal("no") flt = Word(nums + ".-").setParseAction(lambda s, l, t: float(t[0])) integer = Word(nums + "-").setParseAction(lambda s, l, t: int(t[0])) intList = begin + OneOrMore(integer) + stop floatList = begin + OneOrMore(flt) + stop definitionsLine = Literal( "definitions").suppress() + eq + quotedName.setResultsName("quotedName") currentLine = Literal("current").suppress() + eq + flt.setResultsName( "currentValue") localValueLine = Literal("local_value").suppress() + eq + flt.setResultsName( "localValue") outgoingLine = Literal("outgoing").suppress() + eq + flt.setResultsName( "outgoing")
def __init__(self, ffilter=None, filter_string=None): if PYPARSING: quoted_str_value = QuotedString('\'', unquoteResults=True, escChar='\\') int_values = Word("0123456789") error_value = Literal("XXX").setParseAction( self.__compute_xxx_value) bbb_value = Literal("BBB").setParseAction(self.__compute_bbb_value) field_value = Word(alphas + "." + "_" + "-") basic_primitives = int_values | quoted_str_value operator_names = oneOf( "m d e un u r l sw unique startswith decode encode unquote replace lower upper" ).setParseAction(lambda s, l, t: [(l, t[0])]) fuzz_symbol = ( Suppress("FUZ") + Optional(Word("23456789"), 1).setParseAction(lambda s, l, t: [int(t[0]) - 1]) + Suppress("Z")).setParseAction(self.__compute_fuzz_symbol) operator_call = Group( Suppress("|") + operator_names + Suppress("(") + Optional(basic_primitives, None) + Optional(Suppress(",") + basic_primitives, None) + Suppress(")")) fuzz_value = ( fuzz_symbol + Optional(Suppress("[") + field_value + Suppress("]"), None)).setParseAction(self.__compute_fuzz_value) fuzz_value_op = ((fuzz_symbol + Suppress("[") + Optional(field_value)).setParseAction( self.__compute_fuzz_value) + operator_call + Suppress("]")).setParseAction( self.__compute_perl_value) fuzz_value_op2 = ((fuzz_symbol + operator_call).setParseAction( self.__compute_perl_value)) res_value_op = (Word(alphas + "." + "_" + "-").setParseAction( self.__compute_res_value) + Optional(operator_call, None)).setParseAction( self.__compute_perl_value) basic_primitives_op = (basic_primitives + Optional( operator_call, None)).setParseAction(self.__compute_perl_value) fuzz_statement = fuzz_value ^ fuzz_value_op ^ fuzz_value_op2 ^ res_value_op ^ basic_primitives_op operator = oneOf("and or") not_operator = Optional(oneOf("not"), "notpresent") symbol_expr = Group(fuzz_statement + oneOf("= != < > >= <= =~ !~ ~") + (bbb_value ^ error_value ^ fuzz_statement ^ basic_primitives)).setParseAction( self.__compute_expr) definition = fuzz_statement ^ symbol_expr definition_not = not_operator + definition definition_expr = definition_not + ZeroOrMore(operator + definition_not) nested_definition = Group( Suppress("(") + definition_expr + Suppress(")")) nested_definition_not = not_operator + nested_definition self.finalformula = (nested_definition_not ^ definition_expr) + ZeroOrMore(operator + ( nested_definition_not ^ definition_expr)) definition_not.setParseAction(self.__compute_not_operator) nested_definition_not.setParseAction(self.__compute_not_operator) nested_definition.setParseAction(self.__compute_formula) self.finalformula.setParseAction(self.__myreduce) if ffilter is not None and filter_string is not None: raise FuzzExceptInternalError( FuzzException.FATAL, "A filter must be initilized with a filter string or an object, not both" ) self.res = None if ffilter: self.hideparams = ffilter else: self.hideparams = dict(regex_show=None, codes_show=None, codes=[], words=[], lines=[], chars=[], regex=None, filter_string="") if filter_string: self.hideparams['filter_string'] = filter_string self.baseline = None self.stack = {} self._cache = collections.defaultdict(set)