def top_level_mode(self): primitive = self.consume_next_primitive() if isinstance(primitive, Primitive): if primitive.primitive[0] == "identifier": self.current_selector = ElementSelector(primitive.primitive[1]) self.mode = ELEMENT_MODE elif primitive.primitive == ("delim", "*"): self.current_selector = ElementSelector() self.mode = ELEMENT_MODE else: assert False elif isinstance(primitive, SimpleBlock): if primitive.associated_token == ("[",): self.reprocess_current_primitive() self.mode = ATTRIBUTE_MODE else: assert False else: assert False
def attribute_mode(self): block = self.consume_next_primitive() if len(block.value) == 1: if block.value[0].primitive[0] == "identifier": if self.current_selector: attr_selector = AttributeSelector(block.value[0].primitive[1]) self.current_selector.append(attr_selector) else: self.current_selector = AttributeSelector(block.value[0].primitive[1]) else: assert False elif len(block.value) == 3: if ( block.value[0].primitive[0] == "identifier" and block.value[1].primitive[0] == "delim" and block.value[2].primitive[0] == "string" ): attr_selector = AttributeSelector( block.value[0].primitive[1], block.value[2].primitive[1], block.value[1].primitive[1]) self.current_selector.append(attr_selector) else: assert False elif len(block.value) == 4: if ( block.value[0].primitive[0] == "identifier" and block.value[1].primitive[0] == "delim" and block.value[2].primitive[0] == "delim" and block.value[3].primitive[0] == "string" ): attr_selector = AttributeSelector( block.value[0].primitive[1], block.value[3].primitive[1], block.value[1].primitive[1] + block.value[2].primitive[1]) self.current_selector.append(attr_selector) else: assert False else: assert False
class Selector: def __init__(self, s): p = Parser(list(Tokenizer(s + "{}").tokenize())) p.parse() self.primitives = p.open_rule_stack[0].value[0].selector self.index = 0 self.mode = TOP_LEVEL_MODE self.current_selector = None def consume_next_primitive(self): primitive = self.primitives[self.index] self.index += 1 if isinstance(primitive, Primitive) and primitive.primitive[0] == "whitespace": return self.consume_next_primitive() return primitive def reprocess_current_primitive(self): self.index -= 1 def parse(self): while self.index < len(self.primitives): if self.mode == TOP_LEVEL_MODE: self.top_level_mode() elif self.mode == ELEMENT_MODE: self.element_mode() elif self.mode == ATTRIBUTE_MODE: self.attribute_mode() elif self.mode == CHILD_MODE: self.child_mode() elif self.mode == FOLLOWED_BY_MODE: self.followed_by_mode() else: print "UNKNOWN MODE", self.mode quit() return self.current_selector def top_level_mode(self): primitive = self.consume_next_primitive() if isinstance(primitive, Primitive): if primitive.primitive[0] == "identifier": self.current_selector = ElementSelector(primitive.primitive[1]) self.mode = ELEMENT_MODE elif primitive.primitive == ("delim", "*"): self.current_selector = ElementSelector() self.mode = ELEMENT_MODE else: assert False elif isinstance(primitive, SimpleBlock): if primitive.associated_token == ("[",): self.reprocess_current_primitive() self.mode = ATTRIBUTE_MODE else: assert False else: assert False def element_mode(self): primitive = self.consume_next_primitive() if isinstance(primitive, SimpleBlock): if primitive.associated_token == ("[",): self.reprocess_current_primitive() self.mode = ATTRIBUTE_MODE else: assert False elif isinstance(primitive, Primitive): if primitive.primitive[0] == "identifier": self.current_selector = self.current_selector.descendant(ElementSelector(primitive.primitive[1])) elif primitive.primitive == ("delim", ">"): self.mode = CHILD_MODE elif primitive.primitive == ("delim", "*"): self.current_selector = self.current_selector.descendant(ElementSelector()) elif primitive.primitive == ("delim", "+"): self.mode = FOLLOWED_BY_MODE else: assert False else: assert False def child_mode(self): primitive = self.consume_next_primitive() if isinstance(primitive, Primitive) and primitive.primitive[0] == "identifier": self.current_selector = self.current_selector.child(ElementSelector(primitive.primitive[1])) else: assert False def followed_by_mode(self): primitive = self.consume_next_primitive() if isinstance(primitive, Primitive) and primitive.primitive[0] == "identifier": self.current_selector = self.current_selector.followed_by(ElementSelector(primitive.primitive[1])) else: assert False def attribute_mode(self): block = self.consume_next_primitive() if len(block.value) == 1: if block.value[0].primitive[0] == "identifier": if self.current_selector: attr_selector = AttributeSelector(block.value[0].primitive[1]) self.current_selector.append(attr_selector) else: self.current_selector = AttributeSelector(block.value[0].primitive[1]) else: assert False elif len(block.value) == 3: if ( block.value[0].primitive[0] == "identifier" and block.value[1].primitive[0] == "delim" and block.value[2].primitive[0] == "string" ): attr_selector = AttributeSelector( block.value[0].primitive[1], block.value[2].primitive[1], block.value[1].primitive[1]) self.current_selector.append(attr_selector) else: assert False elif len(block.value) == 4: if ( block.value[0].primitive[0] == "identifier" and block.value[1].primitive[0] == "delim" and block.value[2].primitive[0] == "delim" and block.value[3].primitive[0] == "string" ): attr_selector = AttributeSelector( block.value[0].primitive[1], block.value[3].primitive[1], block.value[1].primitive[1] + block.value[2].primitive[1]) self.current_selector.append(attr_selector) else: assert False else: assert False