def test_node_combine(self): node = ntype("int") self.assertTrue(isinstance(ntype("int"), Node)) list( map( self.assertTrue, [ isinstance(nvalue("smth"), Node), isinstance(node + node, Node), isinstance(node | node, Node), isinstance(many(node), Node), isinstance(oneplus(node), Node), isinstance(future(), Node), isinstance(node.join(node), Node), isinstance(maby(node), Node), isinstance(exact("smth"), Node), isinstance(finish(), Node), isinstance(skip(node), Node), ], ) )
def parse(tokens): integer = ntype("int") >> (lambda t: int(t.value)) comma = skip(ntype(",")) obr = skip(ntype("{")) cbr = skip(ntype("}")) br = skip(ntype("'")) orbr = skip(ntype("(")) crbr = skip(ntype(")")) two = skip(ntype(":")) word = ntype("text") >> (lambda t: t.value) string = br + word + br dictionary = future() tuple = future() elem = integer | string | tuple | dictionary tuple.define(orbr + elem.join(comma) + crbr) dictionary.define((obr + (elem + two + elem).join(comma) + cbr >> dict)) parser = dictionary | tuple return parser.parse(tokens)[0]
def parse(self, tokens): #вспомогательные конструкции первого уровня obr = skip(ntype("{")) cbr = skip(ntype("}")) osbr = skip(ntype("[")) csbr = skip(ntype("]")) check = skip(ntype("?")) ref = skip(ntype(">>")) alt = skip(ntype("|")) uns = skip(ntype("#")) star = skip(ntype("@")) twospot = skip(ntype(":")) #текст text = ntype("text") >> self.create_str value = (obr + text + cbr) >> self.create_var reference = (ref + text) >> self.create_ref cycle = (uns + reference + star + text + uns) >> self.create_cycle flag = (obr + text + twospot + (oneplus(text) >> zip) + cbr) >> self.create_flag alternative = future() tryme = future() ctr_ = oneplus(text | value | reference | alternative | flag | cycle | tryme) >> zip ctr = ctr_ + finish() alternative.define((osbr + ctr_.join(alt) + csbr) >> self.create_alter) tryme.define((check + osbr + ctr_.join(alt) + csbr) >> self.create_tryme) return ctr.parse(tokens)[0]
def parse(self, tokens): #======================================================================= # helpers #======================================================================= def create_end(node, ignore=True): def _foo(token): val = getattr(token, "value", token) node.define_with_revert(long_op + skip(exact("/" + val)) + long_cl) return Ignore() if ignore else token return _foo def revert(node, ignore=True): def _foo(token): node.revert() return Ignore() if ignore else token return _foo text = ntype(EXTERNAL) >> (lambda t: TextChunk(t.value)) #======================================================================= # reserved words #======================================================================= rfor = exact("for") rif = exact("if") relse = skip(exact("else")) rin = skip(exact("in")) rblock = (exact("block")) rextend = skip(exact("extend")) rmethod = skip(exact("method")) rstrict = exact("strict") >> (lambda t: t.value) rimplicit = exact("implicit") >> (lambda t: t.value) #======================================================================= # small items #======================================================================= word = ntype("word") >> (lambda t: ContextVar(t.value)) integer = ntype("integer") >> (lambda t: int(t.value)) binopt = ntype("binary") >> (lambda t: select_opt(t.value)) string = ntype("string") >> (lambda t: String(t.value[1:-1])) number = integer twospot = skip(exact(":")) #======================================================================= # границы блоков #======================================================================= short_op = skip(exact(SHORT_OPEN)) short_cl = skip(exact(SHORT_CLOSE)) long_op = skip(exact(LONG_OPEN)) long_cl = skip(exact(LONG_CLOSE)) stuff = future() #======================================================================= # chain chunk #======================================================================= short_meat = future() short_block = short_op + short_meat + short_cl #======================================================================= # function #======================================================================= function = future() function.define((word + skip(exact("(")) + maby((number | string | word | function).join(skip(exact(",")))) + skip(exact(")"))) >> self.__function) #======================================================================= # chain chunk #======================================================================= arrow = skip(exact(">")) short_meat.define((word + many(arrow + function)) >> self.__chain) #======================================================================= # if chunk #======================================================================= endif = future() ifchunk = (long_op + (rif >> create_end(endif)) + (((number | word) + maby(binopt + (number | word))) >> self.__if_head) + long_cl + ((stuff + maby(long_op + relse + long_cl + stuff)) >> self.__if_body) + endif) >> self.__if #======================================================================= # for chunk #======================================================================= endfor = future() forchunk = (long_op + (rfor >> create_end(endfor)) + ((word.join(skip(exact(","))) + rin + (function | word)) >> self.__for_head) + long_cl + (stuff >> list) + endfor) >> self.__for #======================================================================= # block chunk #======================================================================= endblock = future() block_chunk = (long_op + (rblock >> create_end(endblock)) + twospot + word + long_cl + (stuff >> list) + endblock) >> self.__block #======================================================================= # mod chunk #======================================================================= endmod = future() mod_chunk = (long_op + (word >> create_end(endmod, ignore=False)) + ((exact("+") >> (lambda _: True)) | (exact("-") >> (lambda _: False))) + long_cl + (stuff >> list) + (endmod >> revert(endmod))) >> self.__mod #======================================================================= # comment #======================================================================= comment = skip(long_op + exact("#") + string + long_cl) #======================================================================= # extend chunk #======================================================================= extend = (long_op + skip(exact("#")) + rextend + twospot + word + maby(rmethod + twospot + (rstrict | rimplicit)) + long_cl) >> self.__extend #======================================================================= # разный стафф #======================================================================= stuff.define(many( text | short_block | ifchunk | forchunk | block_chunk | mod_chunk | comment | extend)) return [x for x in (stuff + finish()).parse(tokens)[0] if not isinstance(x, Ignore)]
def parse(tokens): integer = ntype("int") >> (lambda t: int(t.value)) point = skip(ntype(".")) parser = integer + maby(point + integer) return parser.parse(tokens)[0]
def parse(tokens): integer = ntype("int") >> (lambda t: int(t.value)) parser = oneplus(integer + integer) return parser.parse(tokens)[0]
def parse(tokens): integer = ntype("int") >> (lambda t: int(t.value)) comma = skip(ntype(",")) parser = many(integer + comma) return parser.parse(tokens)[0]
def parse(tokens): integer = ntype("int") >> (lambda t: int(t.value)) return integer.parse(tokens)[0]
def test_node_creation(self): node = ntype("int") self.assertTrue(isinstance(node, Node))
def parse(tokens): integer = ntype("int") >> (lambda t: int(t.value)) comma = skip(ntype(",")) parser = integer.join(comma) + finish() return parser.parse(tokens)[0]
def parse(tokens): integer = ntype("int") >> (lambda t: int(t.value)) three = exact("3") >> (lambda t: int(t.value)) comma = skip(ntype(",")) parser = integer + comma + three return parser.parse(tokens)[0]