def parse_add_library_standard(ctx, tokens, breakstack, sortable): """ :: add_library(<name> [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] source1 [source2 ...]) :see: https://cmake.org/cmake/help/v3.0/command/add_library.html """ # pylint: disable=too-many-statements parsing_name = 1 parsing_type = 2 parsing_flag = 3 parsing_sources = 4 tree = TreeNode(NodeType.ARGGROUP) # If it is a whitespace token then put it directly in the parse tree at # the current depth while tokens and tokens[0].type in WHITESPACE_TOKENS: tree.children.append(tokens.pop(0)) continue state_ = parsing_name parg_group = None src_group = None active_depth = tree flags = ("STATIC", "SHARED", "MODULE", "OBJECT") while tokens: # This parse function breakson the first right paren, since parenthetical # groups are not allowed. A parenthesis might exist in a filename, but # if so that filename should be quoted so it wont show up as a RIGHT_PAREN # token. if tokens[0].type is TokenType.RIGHT_PAREN: break # If it is a whitespace token then put it directly in the parse tree at # the current depth if tokens[0].type in WHITESPACE_TOKENS: active_depth.children.append(tokens.pop(0)) continue # If it's a comment token not associated with an argument, then put it # directly into the parse tree at the current depth if tokens[0].type in (TokenType.COMMENT, TokenType.BRACKET_COMMENT): if state_ > parsing_name: if get_tag(tokens[0]) in ("unsort", "unsortable"): sortable = False elif get_tag(tokens[0]) in ("sort", "sortable"): sortable = True child = TreeNode(NodeType.COMMENT) active_depth.children.append(child) child.children.append(tokens.pop(0)) continue if state_ is parsing_name: token = tokens.pop(0) parg_group = PositionalGroupNode() parg_group.spec = PositionalSpec("+") active_depth = parg_group tree.children.append(parg_group) child = TreeNode(NodeType.ARGUMENT) child.children.append(token) CommentNode.consume_trailing(ctx, tokens, child) parg_group.children.append(child) state_ += 1 elif state_ is parsing_type: if get_normalized_kwarg(tokens[0]) in flags: token = tokens.pop(0) child = TreeNode(NodeType.FLAG) child.children.append(token) CommentNode.consume_trailing(ctx, tokens, child) parg_group.children.append(child) state_ += 1 elif state_ is parsing_flag: if get_normalized_kwarg(tokens[0]) == "EXCLUDE_FROM_ALL": token = tokens.pop(0) child = TreeNode(NodeType.FLAG) child.children.append(token) CommentNode.consume_trailing(ctx, tokens, child) parg_group.children.append(child) state_ += 1 src_group = PositionalGroupNode(sortable=sortable, tags=["file-list"]) src_group.spec = PositionalSpec("+") active_depth = src_group tree.children.append(src_group) elif state_ is parsing_sources: token = tokens.pop(0) child = TreeNode(NodeType.ARGUMENT) child.children.append(token) CommentNode.consume_trailing(ctx, tokens, child) src_group.children.append(child) if only_comments_and_whitespace_remain(tokens, breakstack): active_depth = tree return tree
def parse(cls, ctx, tokens, npargs, ntup, flags, breakstack): """Parse a continuous sequence of `npargs` positional argument pairs. If npargs is an integer we will consume exactly that many arguments. If it is not an integer then it is a string meaning: * "?": zero or one * "*": zero or more * "+": one or more """ tree = cls() tree.spec = PositionalSpec(ntup, flags=flags, legacy=True) subtree = None active_depth = tree npargs_consumed = 0 ntup_consumed = 0 while tokens: # Break if we have consumed enough positional arguments if pargs_are_full(npargs, npargs_consumed): break # Break if the next token belongs to a parent parser, i.e. if it # matches a keyword argument of something higher in the stack, or if # it closes a parent group. if should_break(tokens[0], breakstack): break # Otherwise we will consume the token token = tokens.pop(0) # If it is a whitespace token then put it directly in the parse tree at # the current depth if token.type in WHITESPACE_TOKENS: active_depth.children.append(token) continue # If it's a comment token not associated with an argument, then put it # directly into the parse tree at the current depth if token.type in (lexer.TokenType.COMMENT, lexer.TokenType.BRACKET_COMMENT): child = CommentNode() tree.children.append(child) child.children.append(token) continue # If it's a sentinel comment, then add it at the current depth if tokens[0].type in (lexer.TokenType.FORMAT_OFF, lexer.TokenType.FORMAT_ON): tree.children.append(OnOffNode.consume(ctx, tokens)) continue if subtree is None: subtree = PositionalGroupNode() subtree.spec = PositionalSpec(2, False, [], flags) tree.children.append(subtree) ntup_consumed = 0 # Otherwise is it is a positional argument, so add it to the tree as such if get_normalized_kwarg(token) in flags: child = TreeNode(NodeType.FLAG) else: child = TreeNode(NodeType.ARGUMENT) child.children.append(token) CommentNode.consume_trailing(ctx, tokens, child) subtree.children.append(child) ntup_consumed += 1 if ntup_consumed >= ntup: npargs_consumed += 1 subtree = None return tree