コード例 #1
0
    def _parse_parameter(self):
        """ Parses single parameter """
        t = self._next_token()
        while t.type == TokenType.NEWLINE or t.value == "\n":
            if not self._tokens_left():
                raise ParseError("Expected parameter at end of string")
            t = self._next_token()

        if t.type == TokenType.NAME:
            # Constant or action used as parameter
            if self._tokens_left() and self._peek_token(
            ).type == TokenType.OP and self._peek_token().value == '(':
                # Action used as parameter
                self.index -= 1  # go step back and reparse as action
                parameter = self._parse_action()
            elif self._tokens_left() and t.value in Action.ALL and type(
                    Action.ALL[
                        t.value]) == dict and self._peek_token().value == '.':
                # SOMETHING.Action used as parameter
                self.index -= 1  # go step back and reparse as action
                parameter = self._parse_action()
            else:
                # Constant
                if not t.value in ActionParser.CONSTS:
                    raise ParseError(
                        "Expected parameter, got '%s' which is not defined" %
                        (t.value, ))
                parameter = ActionParser.CONSTS[t.value]

            # Check for dots
            while self._tokens_left() and self._peek_token(
            ).type == TokenType.OP and self._peek_token().value == '.':
                self._next_token()
                if not self._tokens_left():
                    raise ParseError("Expected NAME after '.'")

                t = self._next_token()
                if not hasattr(parameter, t.value):
                    raise ParseError("%s has no attribute '%s'" % (
                        parameter,
                        t.value,
                    ))
                parameter = getattr(parameter, t.value)

            # Check for ranges (<, >, <=, >=)
            if self._tokens_left() and self._peek_token().type == TokenType.OP:
                if self._peek_token().value in RangeOP.OPS:
                    op = self._next_token().value
                    # TODO: Maybe other axes
                    if parameter not in (STICK, SCButtons.LT, SCButtons.RT,
                                         SCButtons.X, SCButtons.Y):
                        raise ParseError("'%s' is not trigger nor axis" %
                                         (nameof(parameter), ))
                    if not self._tokens_left():
                        raise ParseError("Excepted number after '%s'" % (op, ))
                    try:
                        number = float(self._next_token().value)
                    except ValueError:
                        raise ParseError("Excepted number after '%s'" % (op, ))
                    parameter = RangeOP(parameter, op, number)

            return parameter

        if t.type == TokenType.OP and t.value == "-":
            if not self._tokens_left(
            ) or self._peek_token().type != TokenType.NUMBER:
                raise ParseError("Expected number after '-'")
            return -self._parse_number()

        if t.type == TokenType.NUMBER:
            self.index -= 1
            return self._parse_number()

        if t.type == TokenType.STRING:
            return t.value[1:-1].decode('string_escape')

        raise ParseError("Expected parameter, got '%s'" % (t.value, ))