예제 #1
0
    def _ReadArithSub2Part(self):
        """Non-standard arith sub $[a + 1]."""
        left_span_id = self.cur_token.span_id

        anode = self._ReadArithExpr()
        if not anode:
            self.AddErrorContext("Error parsing arith sub part")
            return None

        if self.token_type != Id.Arith_RBracket:
            self.AddErrorContext("Expected ], got %s", self.cur_token)
            return None
        right_span_id = self.cur_token.span_id

        node = ast.ArithSubPart(anode)
        node.spids.append(left_span_id)
        node.spids.append(right_span_id)
        return node
예제 #2
0
    def _ReadArithSubPart(self):
        """
    Read an arith substitution, which contains an arith expression, e.g.
    $((a + 1)).
    """
        left_span_id = self.cur_token.span_id

        # The second one needs to be disambiguated in stuff like stuff like:
        # $(echo $(( 1+2 )) )
        self.lexer.PushHint(Id.Op_RParen, Id.Right_ArithSub)

        # NOTE: To disambiguate $(( as arith sub vs. command sub and subshell, we
        # could save the lexer/reader state here, and retry if the arithmetic parse
        # fails.  But we can almost always catch this at parse time.  There could
        # be some exceptions like:
        # $((echo * foo))  # looks like multiplication
        # $((echo / foo))  # looks like division

        anode = self._ReadArithExpr()
        if not anode:
            self.AddErrorContext("Error parsing arith sub part")
            return None

        if self.token_type != Id.Arith_RParen:
            self._BadToken('Expected first paren to end arith sub, got %s',
                           self.cur_token)
            return None

        self._Next(LexMode.OUTER)  # TODO: This could be DQ or ARITH too

        # PROBLEM: $(echo $(( 1 + 2 )) )
        # Two right parens break the Id.Eof_RParen scheme
        self._Peek()
        if self.token_type != Id.Right_ArithSub:
            self._BadToken('Expected second paren to end arith sub, got %s',
                           self.cur_token)
            return None
        right_span_id = self.cur_token.span_id

        node = ast.ArithSubPart(anode)
        node.spids.append(left_span_id)
        node.spids.append(right_span_id)
        return node