public StreamNode parse(String name, String stream) {
		this.expressionString = stream;
		Tokenizer tokenizer = new Tokenizer(expressionString);
		tokenStream = tokenizer.getTokens();
		tokenStreamLength = tokenStream.size();
		tokenStreamPointer = 0;
		StreamNode ast = eatStream();

		// Check the stream name, however it was specified
		if (ast.getName() != null && !isValidStreamName(ast.getName())) {
			throw new StreamDefinitionException(ast.getName(), 0, XDDSLMessages.ILLEGAL_STREAM_NAME, ast.getName());
		}
		if (name != null && !isValidStreamName(name)) {
			throw new StreamDefinitionException(name, 0, XDDSLMessages.ILLEGAL_STREAM_NAME, name);
		}

		// Check that each module has a unique label (either explicit or implicit)
		Map<String, ModuleNode> alreadySeen = new LinkedHashMap<String, ModuleNode>();
		for (int m = 0; m < ast.getModuleNodes().size(); m++) {
			ModuleNode node = ast.getModuleNodes().get(m);
			ModuleNode previous = alreadySeen.put(node.getLabelName(), node);
			if (previous != null) {
				String duplicate = node.getLabelName();
				int previousIndex = new ArrayList<String>(alreadySeen.keySet()).indexOf(duplicate);
				throw new StreamDefinitionException(stream, node.startpos, XDDSLMessages.DUPLICATE_LABEL,
						duplicate, previous.getName(), previousIndex, node.getName(), m);
			}
		}

		// Check if the stream name is same as that of any of its modules' names
		// Can lead to infinite recursion during resolution, when parsing a composite module.
		if (ast.getModule(name) != null) {
			throw new StreamDefinitionException(stream, stream.indexOf(name),
					XDDSLMessages.STREAM_NAME_MATCHING_MODULE_NAME,
					name);
		}
		if (moreTokens()) {
			throw new StreamDefinitionException(this.expressionString, peekToken().startpos, XDDSLMessages.MORE_INPUT,
					toString(nextToken()));
		}
		ast.resolve(this, this.expressionString);
		return ast;
	}
Parse a stream definition.

@return the AST for the parsed stream
@throws StreamDefinitionException
spring-xd-dirt/src/main/java/org/springframework/xd/dirt/stream/dsl/StreamConfigParser.java