Ejemplo n.º 1
0
// Parse returns all of the documents in the stream.
func (parser *Parser) Parse() (docs []*Document, err error) {
	docs = make([]*Document, 0, 1)

docLoop:
	for {
		var newDoc *Document

		// Parse document
		newDoc, err = parser.ParseDocument()
		if err != nil {
			return
		}

		// Add document to array
		if cap(docs) < len(docs)+1 {
			newDocs := make([]*Document, len(docs), cap(docs)*2)
			copy(newDocs, docs)
			docs = newDocs
		}
		docs = docs[0 : len(docs)+1]
		docs[len(docs)-1] = newDoc

		// Eat up any end document tokens
	endDocLoop:
		for {
			var tok scanner.Token

			if tok, err = parser.scan(); err != nil {
				return
			}

			switch tok.GetKind() {
			case token.DOCUMENT_END:
				// Ignore
			case token.STREAM_END:
				break docLoop
			default:
				parser.unscan(tok)
				break endDocLoop
			}
		}
	}
	return
}
Ejemplo n.º 2
0
func (parser *Parser) parseDocHeader() (err error) {
	startedHeader := false

	for {
		var tok scanner.Token
		tok, err = parser.scan()
		if err != nil {
			return
		}

		switch tok.GetKind() {
		case token.STREAM_START:
			// Ignore
		case token.VERSION_DIRECTIVE:
			startedHeader = true
			versionDir := tok.(scanner.VersionDirective)
			parser.doc.MajorVersion, parser.doc.MinorVersion = versionDir.Major, versionDir.Minor
		case token.TAG_DIRECTIVE:
			startedHeader = true
			if err = parser.handleTagDirective(tok.(scanner.TagDirective)); err != nil {
				return
			}
		case token.DOCUMENT_START:
			return
		case token.DOCUMENT_END:
			if startedHeader {
				err = errors.New("End document token appeared after directives")
				return
			}
		default:
			parser.unscan(tok)
			return
		}
	}

	// This should never be reached.
	return nil
}
Ejemplo n.º 3
0
func (parser *Parser) parseMapping(block bool) (node *Mapping, err error) {
	var tok scanner.Token
	var sentinel token.Token

	// Discard opening token
	if tok, err = parser.scan(); err != nil {
		return
	}

	if block {
		sentinel = token.BLOCK_END
	} else {
		sentinel = token.FLOW_MAPPING_END
	}

	node = new(Mapping)
	node.basicNode = new(basicNode)
	node.pos = tok.GetStart()
	node.Pairs = make([]KeyValuePair, 0, 2)
	pairCount := 0

	for err == nil && tok.GetKind() != sentinel {
		var pair KeyValuePair

		// Scan key
		tok, err = parser.scan()
		if err != nil {
			return
		} else if tok.GetKind() != token.KEY {
			err = errors.New("Expected key")
			return
		}
		pair.Key, err = parser.parseNode()
		if err != nil {
			return
		}

		// Scan value
		tok, err = parser.scan()
		if err != nil {
			return
		} else if tok.GetKind() != token.VALUE {
			err = errors.New("Expected value")
			return
		}
		pair.Value, err = parser.parseNode()
		if err != nil {
			return
		}

		// Add pair to node
		if cap(node.Pairs) < pairCount+1 {
			newPairs := make([]KeyValuePair, pairCount, cap(node.Pairs)*2)
			copy(newPairs, node.Pairs)
			node.Pairs = newPairs
		}
		node.Pairs = node.Pairs[0 : pairCount+1]
		node.Pairs[pairCount] = pair
		pairCount++

		// Find closure
		// Wouldn't it be great if it were always this easy?
		tok, err = parser.scan()
		if err != nil {
			return
		} else if !(tok.GetKind() == sentinel || (!block && tok.GetKind() == token.FLOW_ENTRY) || (block && tok.GetKind() == token.KEY)) {
			err = errors.New("Unexpected token in mapping: " + tok.GetKind().String() + " " + tok.String())
			return
		}

		if tok.GetKind() == token.KEY {
			parser.unscan(tok)
		}
	}

	return
}
Ejemplo n.º 4
0
func (parser *Parser) parseSequence(block bool) (node *Sequence, err error) {
	var tok scanner.Token
	var sep, sentinel token.Token

	// Discard opening token
	if tok, err = parser.scan(); err != nil {
		return
	}

	if block {
		sep, sentinel = token.BLOCK_ENTRY, token.BLOCK_END
	} else {
		sep, sentinel = token.FLOW_ENTRY, token.FLOW_SEQUENCE_END
	}

	node = new(Sequence)
	node.basicNode = new(basicNode)
	node.pos = tok.GetStart()
	node.Nodes = make([]Node, 0, 2)
	childCount := 0

	// Block sequences have a leading separator
	if block {
		tok, err = parser.scan()
		if tok.GetKind() != sep {
			err = errors.New("Expected leading block entry token")
			return
		}
	}

	for err == nil && tok.GetKind() != sentinel {
		var child Node

		// Scan child
		if child, err = parser.parseNode(); err != nil {
			return
		}

		// Add child to node
		if cap(node.Nodes) < childCount+1 {
			newNodes := make([]Node, childCount, cap(node.Nodes)*2)
			copy(newNodes, node.Nodes)
			node.Nodes = newNodes
		}
		node.Nodes = node.Nodes[0 : childCount+1]
		node.Nodes[childCount] = child
		childCount++

		// Check for separator
		tok, err = parser.scan()
		if err != nil {
			return
		} else if tok.GetKind() != sep && tok.GetKind() != sentinel {
			err = errors.New("Unexpected token in sequence: " + tok.String())
			return
		}
	}
	return
}
Ejemplo n.º 5
0
func (parser *Parser) parseNodeProperties() (anchor, tag string, err error) {
	var tok, tagTok scanner.Token

	if tok, err = parser.scan(); err != nil {
		return
	}

	if tok.GetKind() == token.ANCHOR {
		anchor = tok.String()

		if tok, err = parser.peek(); err != nil {
			return
		}
		if tok.GetKind() == token.TAG {
			tagTok = tok
			parser.scan()
		}
	} else if tok.GetKind() == token.TAG {
		tagTok = tok

		if tok, err = parser.peek(); err != nil {
			return
		}
		if tok.GetKind() == token.ANCHOR {
			anchor = tok.String()
			parser.scan()
		}
	} else {
		parser.unscan(tok)
	}

	if tagTok != nil {
		tag, err = parser.resolveTag(tagTok.(scanner.TagToken))
	}

	return
}