示例#1
0
文件: parser.py 项目: bormog/YASI
    def select_expr(self) -> nodes.Node:
        """
        select_expr -> expr | ID (COMMA ID)* FROM ID (WHERE assignee_sub_stmt (AND assignee_sub_stmt)* (order_sub_stmt)? (limit_sub_stmt)?)?
        Example: select 1+1
        Example: select foo from foobar
        Example: select foo, bar from foobar where foo='foo', bar=100500
        """

        if self.token.type == TokenType.ID:
            result = []

            column = nodes.Column(self.token)
            self.move_forward(TokenType.ID)
            result.append(column)
            while self.token.type == TokenType.COMMA:
                self.move_forward(TokenType.COMMA)
                column = nodes.Column(self.token)
                self.move_forward(TokenType.ID)
                result.append(column)

            self.move_forward(TokenType.FROM)
            table = nodes.Table(self.token)
            self.move_forward(TokenType.ID)

            where = []
            if self.token.type == TokenType.WHERE:
                self.move_forward(TokenType.WHERE)
                where.append(self.assignee_sub_stmt())

                while self.token.type == TokenType.AND:
                    self.move_forward(TokenType.AND)
                    where.append(self.assignee_sub_stmt())

            if self.token.type == TokenType.ORDER:
                order = self.order_sub_stmt()
            else:
                order = nodes.Empty()

            if self.token.type == TokenType.LIMIT:
                limit = self.limit_sub_stmt()
            else:
                limit = nodes.Empty()

            node = nodes.SelectStatement(
                table=table,
                result=result,
                where=where,
                order=order,
                limit=limit
            )
        else:
            node = nodes.SelectStatement(
                table=nodes.Empty(),
                result=self.expr(),
                where=None,
                order=nodes.Empty(),
                limit=nodes.Empty()
            )
        return node
示例#2
0
 def test_or(self):
     self._compare('a|b', N.Or(N.Char('a'), N.Char('b')))
     self._compare('ab|c',
                   N.Or(N.Concat(N.Char('a'), N.Char('b')), N.Char('c')))
     self._compare('a|bc',
                   N.Or(N.Char('a'), N.Concat(N.Char('b'), N.Char('c'))))
     self._compare('a|b|c', N.Or(N.Or(N.Char('a'), N.Char('b')),
                                 N.Char('c')))
     self._compare('|', N.Or(N.Empty(), N.Empty()))
示例#3
0
def from_string(regex):
    # regex: str -> node: RegexNode
    if not regex:
        return nodes.Empty()
    state = ParseState()
    for i, c in enumerate(regex):
        if state.level == 0:
            if any(type_.char == c for type_ in nodes.UNARY_NODE_TYPES):
                if state.state != ParseState.BINARY:
                    state.state = ParseState.UNARY
                    state.opr_type = next(t for t in nodes.UNARY_NODE_TYPES
                                          if t.char == c)
                    state.opr_index = i
            elif c == nodes.Or.char:
                state.opr_type = nodes.Or
                state.opr_index = i
                state.state = ParseState.BINARY
            elif state.state != ParseState.BINARY or state.opr_type != nodes.Or:
                if i > 0:
                    state.state = ParseState.BINARY
                    state.opr_type = nodes.Concat
                    state.opr_index = i
        if c == '(':
            state.level += 1
        elif c == ')':
            state.level -= 1

    if state.state == ParseState.NO_OPR:
        if regex[0] == '(' and regex[-1] == ')':
            return from_string(regex[1:-1])
        assert len(regex) == 1, 'Unexpected regex: {}'.format(regex)
        return nodes.Char(regex)
    elif state.state == ParseState.UNARY:
        assert state.opr_index == len(
            regex) - 1, 'Invalid sub-regex: {}'.format(regex)
        return state.opr_type(from_string(regex[:state.opr_index]))
    elif state.state == ParseState.BINARY:
        return state.opr_type(
            from_string(regex[:state.opr_index]),
            from_string(regex[state.opr_index + len(state.opr_type.char):]))
    else:
        raise Exception('Unknown state: {}'.format(state.state))
示例#4
0
 def test_parentheses(self):
     self._compare('()', N.Empty())
     self._compare('(ab)+', N.OneOrMore(N.Concat(N.Char('a'), N.Char('b'))))
     self._compare('a(b)+', N.Concat(N.Char('a'), N.OneOrMore(N.Char('b'))))
     parse.from_string('a(bcd*|efgh?(jk)+)*')
示例#5
0
 def test_empty(self):
     self._compare('', N.Empty())
     self._compare('a|', N.Or(N.Char('a'), N.Empty()))
     self._compare('|a', N.Or(N.Empty(), N.Char('a')))