示例#1
0
    def _read_float(self, reader):
        start = reader.get_cursor()
        result = ""
        while reader.can_read():
            char = reader.peek()
            if char == ".":
                reader.skip()
                if reader.can_read() and reader.peek() == ".":
                    break
                result += char
            elif char.isdigit() or char == "+" or char == "-":
                reader.skip()
                result += char
            else:
                break
        if not result:
            raise BuiltInExceptions.reader_expected_float(
            ).create_with_context(reader)

        # Verify result is a valid float
        try:
            return float(result)
        except ValueError:
            reader.set_cursor(start)
            raise BuiltInExceptions.reader_invalid_float().create_with_context(
                reader, result)
    def parse_nodes(self, node, original_reader, context_so_far):
        source = context_so_far.get_source()
        errors = None
        potentials = None
        cursor = original_reader.get_cursor()

        for child in node.get_relevant_nodes(original_reader):
            if not child.can_use(source):
                continue

            context = context_so_far.copy()
            reader = StringReader(original_reader)
            try:
                try:
                    child.parse(reader, context)
                # TODO: check if this one's appropriate
                except RuntimeError as e:
                    raise BuiltInExceptions.dispatcher_parse_expection(
                    ).create_with_context(reader, e)

                if reader.can_read():
                    if reader.peek() != ARGUMENT_SEPARATOR_CHAR:
                        raise BuiltInExceptions.dispatcher_expected_argument_separator(
                        ).create_with_context(reader)
            except CommandSyntaxException as e:
                if errors is None:
                    errors = {}
                errors[child] = e
                reader.set_cursor(cursor)
                continue

            context.with_command(child.get_command())
            if reader.can_read(2 if child.get_redirect() is None else 1):
                reader.skip()
                if child.get_redirect() is not None:
                    child_context = CommandContextBuilder(
                        self, source, child.get_redirect(),
                        reader.get_cursor())
                    parse = self.parse_nodes(child.get_redirect(), reader,
                                             child_context)
                    context.with_child(parse.get_context())
                    return ParseResult(context, parse.get_reader(),
                                       parse.get_exceptions())
                else:
                    parse = self.parse_nodes(child, reader, context)
                    if potentials is None:
                        potentials = []
                    potentials.append(parse)
            else:
                if potentials is None:
                    potentials = []
                potentials.append(ParseResult(context, reader, {}))

        if potentials:
            potentials.sort(key=functools.cmp_to_key(potentials_cmp))
            return potentials[0]
        return ParseResult(context_so_far, original_reader,
                           {} if errors is None else errors)
    def parse(self, reader):
        start = reader.get_cursor()
        result = reader.read_double()

        if result < self.minimum:
            reader.set_cursor(start)
            raise BuiltInExceptions.float_too_low().create_with_context(reader, result, self.minimum)
        
        if result > self.minimum:
            reader.set_cursor(start)
            raise BuiltInExceptions.float_too_high().create_with_context(reader, result, self.maximum)

        return result
示例#4
0
 def read_int(self):
     start = self.cursor
     while self.can_read() and self.is_allowed_number(self.peek()):
         self.skip()
     
     number = self.string[start:self.cursor]
     if not number:
         raise BuiltInExceptions.reader_expected_int().create_with_context(self)
     
     try:
         return int(number)
     except ValueError:
         self.cursor = start
         raise BuiltInExceptions.reader_invalid_int().create_with_context(self, number)
示例#5
0
    def read_boolean(self):
        start = self.cursor
        value = self.read_unquoted_string()

        if not value:
            raise BuiltInExceptions.reader_expected_bool().create_with_context(self)

        if value == "true":
            return True
        elif value == "false":
            return False
        else:
            self.cursor = start
            raise BuiltInExceptions.reader_invalid_bool().create_with_context(self, value)
    def parse(self, reader, context_builder):
        start = reader.get_cursor()
        end = self.__parse(reader)
        if end > -1:
            context_builder.with_node(self, between(start, end))
            return

        raise BuiltInExceptions.literal_incorrect().create_with_context(
            reader, self.literal)
def test_execute_incorrect_literal():
    subject = CommandDispatcher()
    subject.register(literal("foo").executes(command).then(literal("bar")))

    try:
        subject.execute("foo baz", {})
    except CommandSyntaxException as error:
        assert error.get_type() == BuiltInExceptions.dispatcher_unknown_argument()
        assert error.get_cursor() == 4
def test_execute_empty_command():
    subject = CommandDispatcher()
    subject.register(literal(""))
        
    try:
        subject.execute("", {})
    except CommandSyntaxException as error:
        assert error.get_type() == BuiltInExceptions.dispatcher_unknown_command()
        assert error.get_cursor() == 0
def test_execute_impermissible_command():
    subject = CommandDispatcher()
    subject.register(literal("foo").requires(lambda _: False))
    
    try:
        subject.execute("foo", {})
    except CommandSyntaxException as error:
        assert error.get_type() == BuiltInExceptions.dispatcher_unknown_command()
        assert error.get_cursor() == 0
示例#10
0
 def read_string_until(self, terminator):
     result = ""
     escaped = False
     while self.can_read():
         char = self.read()
         if escaped:
             if char == terminator or char == self.SYNTAX_ESCAPE:
                 result += char
             else:
                 self.set_cursor(self.get_cursor() - 1)
                 raise BuiltInExceptions.reader_invalid_escape().create_with_context(self, str(char))
         elif char == self.SYNTAX_ESCAPE:
             escaped = True
         elif char == terminator:
             return result
         else:
             result += char
     
     raise BuiltInExceptions.reader_expected_end_of_quote().create_with_context(self)
示例#11
0
 def read_quoted_string(self):
     if not self.can_read():
         return ""
     
     next_char = self.peek()
     if not self.is_quoted_string_start(next_char):
         raise BuiltInExceptions.reader_expected_start_of_quote().create_with_context(self)
     
     self.skip()
     return self.read_string_until(next_char)
    def execute_preparsed(self, parse):

        if parse.get_reader().can_read():
            if len(parse.get_exceptions()) == 1:
                raise list(parse.get_exceptions().values())[0]
            elif not parse.get_context().get_range():
                raise BuiltInExceptions.dispatcher_unknown_command(
                ).create_with_context(parse.get_reader())
            else:
                raise BuiltInExceptions.dispatcher_unknown_argument(
                ).create_with_context(parse.get_reader())

        result = 0
        successful_forks = 0
        forked = False
        found_command = False
        command = parse.get_reader().get_string()
        original = parse.get_context().build(command)
        contexts = [original]
        _next = None

        while contexts is not None:
            for context in contexts:
                child = context.get_child()
                if child is not None:
                    forked |= context.is_forked()
                    if child.has_nodes():
                        found_command = True
                        modifier = context.get_redirect_modifier()
                        if modifier is None:
                            if _next is None:
                                _next = []
                            _next.append(child.copy_for(context.get_source()))
                        else:
                            try:
                                results = modifier(context)
                                if results:
                                    if _next is None:
                                        _next = []
                                    for source in results:
                                        _next.append(child.copy_for(source))
                            except CommandSyntaxException as e:
                                self.consumer.on_command_complete(
                                    context, False, 0)
                                if not forked:
                                    raise e
                elif context.get_command() is not None:
                    found_command = True
                    try:
                        value = context.get_command()(context)
                        result += value if value else 1
                        self.consumer.on_command_complete(context, True, value)
                        successful_forks += 1
                    except CommandSyntaxException as e:
                        self.consumer.on_command_complete(context, False, 0)
                        if not forked:
                            raise e

            contexts = _next
            _next = None

        if not found_command:
            self.consumer.on_command_complete(original, False, 0)
            raise BuiltInExceptions.dispatcher_unknown_command(
            ).create_with_context(parse.get_reader())

        return successful_forks if forked else result
示例#13
0
 def expect(self, char):
     if not self.can_read() or self.peek() != char:
         raise BuiltInExceptions.reader_expected_symbol().create_with_context(self, str(char))
         
     self.skip()