Ejemplo n.º 1
0
    def _ReadArithSub2Part(self):
        # type: () -> word_part__ArithSubPart
        """Non-standard arith sub $[a + 1]."""
        left_span_id = self.cur_token.span_id

        self._Next(lex_mode_e.Arith)
        anode = self._ReadArithExpr()
        if self.token_type != Id.Arith_RBracket:
            p_die('Expected ], got %r',
                  self.cur_token.val,
                  token=self.cur_token)

        right_span_id = self.cur_token.span_id

        node = word_part.ArithSubPart(anode)
        node.spids.append(left_span_id)
        node.spids.append(right_span_id)
        return node
Ejemplo n.º 2
0
    def _ReadArithSubPart(self):
        # type: () -> word_part__ArithSubPart
        """
    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

        self._Next(lex_mode_e.Arith)
        anode = self._ReadArithExpr()
        if self.token_type != Id.Arith_RParen:
            p_die('Expected first ) to end arith sub, got %r',
                  self.cur_token.val,
                  token=self.cur_token)

        self._Next(lex_mode_e.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:
            p_die('Expected second ) to end arith sub, got %r',
                  self.cur_token.val,
                  token=self.cur_token)

        right_span_id = self.cur_token.span_id

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