Example #1
0
    def _NextOne(self, lex_mode=lex_mode_e.DBracket):
        n = len(self.words)
        if n == 2:
            assert lex_mode == lex_mode_e.DBracket
            self.words[0] = self.words[1]
            self.cur_word = self.words[0]
            del self.words[1]
        elif n in (0, 1):
            w = self.w_parser.ReadWord(lex_mode)  # may raise
            if n == 0:
                self.words.append(w)
            else:
                self.words[0] = w
            self.cur_word = w

        assert self.cur_word is not None
        self.op_id = word.BoolId(self.cur_word)
        self.b_kind = LookupKind(self.op_id)
Example #2
0
    def ParseFactor(self):
        """
    Factor  : WORD
            | UNARY_OP WORD
            | WORD BINARY_OP WORD
            | '(' Expr ')'
    """
        if self.b_kind == Kind.BoolUnary:
            # Just save the type and not the token itself?
            op = self.op_id
            self._Next()
            w = self.cur_word
            # e.g. [[ -f < ]].  But [[ -f '<' ]] is OK
            if w.tag not in (word_e.CompoundWord, word_e.StringWord):
                p_die('Invalid argument to unary operator', word=w)
            self._Next()
            node = bool_expr.BoolUnary(op, w)
            return node

        if self.b_kind == Kind.Word:
            # Peek ahead another token.
            t2 = self._LookAhead()
            t2_op_id = word.BoolId(t2)
            t2_b_kind = LookupKind(t2_op_id)

            #log('t2 %s / t2_op_id %s / t2_b_kind %s', t2, t2_op_id, t2_b_kind)
            # Redir pun for < and >, -a and -o pun
            if t2_b_kind in (Kind.BoolBinary, Kind.Redir):
                left = self.cur_word

                self._Next()
                op = self.op_id

                # TODO: Need to change to lex_mode_e.BashRegex.
                # _Next(lex_mode) then?
                is_regex = t2_op_id == Id.BoolBinary_EqualTilde
                if is_regex:
                    self._Next(lex_mode=lex_mode_e.BashRegex)
                else:
                    self._Next()

                right = self.cur_word
                if is_regex:
                    # NOTE: StaticEval for checking regex syntax isn't enough.  We could
                    # need to pass do_ere so that the quoted parts get escaped.
                    #ok, s, unused_quoted = word.StaticEval(right)
                    pass

                self._Next()
                return bool_expr.BoolBinary(op, left, right)
            else:
                # [[ foo ]]
                w = self.cur_word
                self._Next()
                return bool_expr.WordTest(w)

        if self.op_id == Id.Op_LParen:
            self._Next()
            node = self.ParseExpr()
            if self.op_id != Id.Op_RParen:
                p_die('Expected ), got %s', self.cur_word, word=self.cur_word)
            self._Next()
            return node

        # It's not WORD, UNARY_OP, or '('
        p_die('Unexpected token in boolean expression', word=self.cur_word)