Beispiel #1
0
    def _ReadArrayLiteralPart(self):
        self._Next(lex_mode_e.OUTER)  # advance past (
        self._Peek()
        if self.cur_token.id != Id.Op_LParen:
            self.AddErrorContext('Expected ( after =', token=self.cur_token)
            return None

        # MUST use a new word parser (with same lexer).
        w_parser = WordParser(self.lexer, self.line_reader)
        words = []
        while True:
            w = w_parser.ReadWord(lex_mode_e.OUTER)
            if not w:
                self.error_stack.extend(w_parser.Error())
                return None

            if w.tag == word_e.TokenWord:
                word_id = word.CommandId(w)
                if word_id == Id.Right_ArrayLiteral:
                    break
                # Unlike command parsing, array parsing allows embedded \n.
                elif word_id == Id.Op_Newline:
                    continue
                else:
                    self.AddErrorContext(
                        'Unexpected word in array literal: %s', w, word=w)
                    return None

            words.append(w)

        words2 = braces.BraceDetectAll(words)
        words3 = word.TildeDetectAll(words2)

        return ast.ArrayLiteralPart(words3)
Beispiel #2
0
    def _ReadArrayLiteralPart(self):
        self._Next(lex_mode_e.OUTER)  # advance past (
        self._Peek()
        if self.cur_token.id != Id.Op_LParen:
            p_die('Expected ( after =, got %r',
                  self.cur_token.val,
                  token=self.cur_token)

        # MUST use a new word parser (with same lexer).
        w_parser = WordParser(self.parse_ctx, self.lexer, self.line_reader)
        words = []
        while True:
            w = w_parser.ReadWord(lex_mode_e.OUTER)
            assert w is not None

            if w.tag == word_e.TokenWord:
                word_id = word.CommandId(w)
                if word_id == Id.Right_ArrayLiteral:
                    break
                # Unlike command parsing, array parsing allows embedded \n.
                elif word_id == Id.Op_Newline:
                    continue
                else:
                    # TokenWord
                    p_die('Unexpected token in array literal: %r',
                          w.token.val,
                          word=w)

            words.append(w)

        words2 = braces.BraceDetectAll(words)
        words3 = word.TildeDetectAll(words2)

        return ast.ArrayLiteralPart(words3)
Beispiel #3
0
  def _ParseForEachLoop(self):
    node = ast.ForEach()
    node.do_arg_iter = False

    ok, iter_name, quoted = word.StaticEval(self.cur_word)
    if not ok or quoted:
      self.AddErrorContext(
          "Invalid for loop variable", word=self.cur_word)
      return None
    if not VAR_NAME_RE.match(iter_name):
      self.AddErrorContext(
          "Invalid for loop variable name", word=self.cur_word)
      return None
    node.iter_name = iter_name
    self._Next()  # skip past name

    if not self._NewlineOk(): return None

    in_spid = const.NO_INTEGER
    semi_spid = const.NO_INTEGER

    if not self._Peek(): return None
    if self.c_id == Id.KW_In:
      self._Next()  # skip in

      in_spid = word.LeftMostSpanForWord(self.cur_word) + 1
      x = self.ParseForWords()
      if x is None:
        return None
      iter_words, semi_spid = x
      words2 = braces.BraceDetectAll(iter_words)
      words3 = word.TildeDetectAll(words2)

      if iter_words is None:  # empty list of words is OK
        return None
      node.iter_words = words3

    elif self.c_id == Id.Op_Semi:
      node.do_arg_iter = True  # implicit for loop
      self._Next()

    elif self.c_id == Id.KW_Do:
      node.do_arg_iter = True  # implicit for loop
      # do not advance

    else:
      self.AddErrorContext("Unexpected word in for loop: %s", self.cur_word,
          word=self.cur_word)
      return None

    node.spids.extend((in_spid, semi_spid))

    body_node = self.ParseDoGroup()
    if not body_node: return None

    node.body = body_node
    return node
Beispiel #4
0
    def _ReadArrayLiteralPart(self):
        self._Next(LexMode.OUTER)  # advance past (
        self._Peek()
        assert self.cur_token.id == Id.Op_LParen, self.cur_token

        # MUST use a new word parser (with same lexer).
        w_parser = WordParser(self.lexer, self.line_reader)
        words = []
        while True:
            w = w_parser.ReadWord(LexMode.OUTER)
            if word.CommandId(w) == Id.Right_ArrayLiteral:
                break

            words.append(w)

        words2 = braces.BraceDetectAll(words)
        words3 = word.TildeDetectAll(words2)

        return ast.ArrayLiteralPart(words3)
Beispiel #5
0
  def _MakeSimpleCommand(self, prefix_bindings, suffix_words, redirects):
    # FOO=(1 2 3) ls is not allowed
    for k, _, v, _ in prefix_bindings:
      if word.HasArrayPart(v):
        self.AddErrorContext(
            'Unexpected array literal in binding: %s', v, word=v)
        return None

    # echo FOO=(1 2 3) is not allowed
    # NOTE: Other checks can be inserted here.  Can resolve builtins,
    # functions, aliases, static PATH, etc.
    for w in suffix_words:
      kov = word.LooksLikeAssignment(w)
      if kov:
        _, _, v = kov
        if word.HasArrayPart(v):
          self.AddErrorContext('Unexpected array literal: %s', v, word=w)
          return None

    # NOTE: # In bash, {~bob,~jane}/src works, even though ~ isn't the leading
    # character of the initial word.
    # However, this means we must do tilde detection AFTER brace EXPANSION, not
    # just after brace DETECTION like we're doing here.
    # The BracedWordTree instances have to be expanded into CompoundWord instances
    # for the tilde detection to work.
    words2 = braces.BraceDetectAll(suffix_words)
    words3 = word.TildeDetectAll(words2)

    node = ast.SimpleCommand()
    node.words = words3
    node.redirects = redirects
    for name, op, val, left_spid in prefix_bindings:
      if op != assign_op_e.Equal:
        # NOTE: Using spid of RHS for now, since we don't have one for op.
        self.AddErrorContext('Expected = in environment binding, got +=',
            word=val)
        return None
      pair = ast.env_pair(name, val)
      pair.spids.append(left_spid)
      node.more_env.append(pair)
    return node