633 lines
21 KiB
JavaScript
633 lines
21 KiB
JavaScript
(function() {
|
|
var MarkedYAMLError, events, tokens, _ref,
|
|
__hasProp = {}.hasOwnProperty,
|
|
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
__slice = [].slice;
|
|
|
|
events = require('./events');
|
|
|
|
MarkedYAMLError = require('./errors').MarkedYAMLError;
|
|
|
|
tokens = require('./tokens');
|
|
|
|
this.ParserError = (function(_super) {
|
|
__extends(ParserError, _super);
|
|
|
|
function ParserError() {
|
|
_ref = ParserError.__super__.constructor.apply(this, arguments);
|
|
return _ref;
|
|
}
|
|
|
|
return ParserError;
|
|
|
|
})(MarkedYAMLError);
|
|
|
|
this.Parser = (function() {
|
|
var DEFAULT_TAGS;
|
|
|
|
DEFAULT_TAGS = {
|
|
'!': '!',
|
|
'!!': 'tag:yaml.org,2002:'
|
|
};
|
|
|
|
function Parser() {
|
|
this.current_event = null;
|
|
this.yaml_version = null;
|
|
this.tag_handles = {};
|
|
this.states = [];
|
|
this.marks = [];
|
|
this.state = 'parse_stream_start';
|
|
}
|
|
|
|
/*
|
|
Reset the state attributes.
|
|
*/
|
|
|
|
|
|
Parser.prototype.dispose = function() {
|
|
this.states = [];
|
|
return this.state = null;
|
|
};
|
|
|
|
/*
|
|
Check the type of the next event.
|
|
*/
|
|
|
|
|
|
Parser.prototype.check_event = function() {
|
|
var choice, choices, _i, _len;
|
|
|
|
choices = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
|
if (this.current_event === null) {
|
|
if (this.state != null) {
|
|
this.current_event = this[this.state]();
|
|
}
|
|
}
|
|
if (this.current_event !== null) {
|
|
if (choices.length === 0) {
|
|
return true;
|
|
}
|
|
for (_i = 0, _len = choices.length; _i < _len; _i++) {
|
|
choice = choices[_i];
|
|
if (this.current_event instanceof choice) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/*
|
|
Get the next event.
|
|
*/
|
|
|
|
|
|
Parser.prototype.peek_event = function() {
|
|
if (this.current_event === null && (this.state != null)) {
|
|
this.current_event = this[this.state]();
|
|
}
|
|
return this.current_event;
|
|
};
|
|
|
|
/*
|
|
Get the event and proceed further.
|
|
*/
|
|
|
|
|
|
Parser.prototype.get_event = function() {
|
|
var event;
|
|
|
|
if (this.current_event === null && (this.state != null)) {
|
|
this.current_event = this[this.state]();
|
|
}
|
|
event = this.current_event;
|
|
this.current_event = null;
|
|
return event;
|
|
};
|
|
|
|
/*
|
|
Parse the stream start.
|
|
*/
|
|
|
|
|
|
Parser.prototype.parse_stream_start = function() {
|
|
var event, token;
|
|
|
|
token = this.get_token();
|
|
event = new events.StreamStartEvent(token.start_mark, token.end_mark);
|
|
this.state = 'parse_implicit_document_start';
|
|
return event;
|
|
};
|
|
|
|
/*
|
|
Parse an implicit document.
|
|
*/
|
|
|
|
|
|
Parser.prototype.parse_implicit_document_start = function() {
|
|
var end_mark, event, start_mark, token;
|
|
|
|
if (!this.check_token(tokens.DirectiveToken, tokens.DocumentStartToken, tokens.StreamEndToken)) {
|
|
this.tag_handles = DEFAULT_TAGS;
|
|
token = this.peek_token();
|
|
start_mark = end_mark = token.start_mark;
|
|
event = new events.DocumentStartEvent(start_mark, end_mark, false);
|
|
this.states.push('parse_document_end');
|
|
this.state = 'parse_block_node';
|
|
return event;
|
|
} else {
|
|
return this.parse_document_start();
|
|
}
|
|
};
|
|
|
|
/*
|
|
Parse an explicit document.
|
|
*/
|
|
|
|
|
|
Parser.prototype.parse_document_start = function() {
|
|
var end_mark, event, start_mark, tags, token, version, _ref1;
|
|
|
|
while (this.check_token(tokens.DocumentEndToken)) {
|
|
this.get_token();
|
|
}
|
|
if (!this.check_token(tokens.StreamEndToken)) {
|
|
start_mark = this.peek_token().start_mark;
|
|
_ref1 = this.process_directives(), version = _ref1[0], tags = _ref1[1];
|
|
if (!this.check_token(tokens.DocumentStartToken)) {
|
|
throw new exports.ParserError("expected '<document start>', but found " + (this.peek_token().id), this.peek_token().start_mark);
|
|
}
|
|
token = this.get_token();
|
|
end_mark = token.end_mark;
|
|
event = new events.DocumentStartEvent(start_mark, end_mark, true, version, tags);
|
|
this.states.push('parse_document_end');
|
|
this.state = 'parse_document_content';
|
|
} else {
|
|
token = this.get_token();
|
|
event = new events.StreamEndEvent(token.start_mark, token.end_mark);
|
|
if (this.states.length !== 0) {
|
|
throw new Error('assertion error, states should be empty');
|
|
}
|
|
if (this.marks.length !== 0) {
|
|
throw new Error('assertion error, marks should be empty');
|
|
}
|
|
this.state = null;
|
|
}
|
|
return event;
|
|
};
|
|
|
|
/*
|
|
Parse the document end.
|
|
*/
|
|
|
|
|
|
Parser.prototype.parse_document_end = function() {
|
|
var end_mark, event, explicit, start_mark, token;
|
|
|
|
token = this.peek_token();
|
|
start_mark = end_mark = token.start_mark;
|
|
explicit = false;
|
|
if (this.check_token(tokens.DocumentEndToken)) {
|
|
token = this.get_token();
|
|
end_mark = token.end_mark;
|
|
explicit = true;
|
|
}
|
|
event = new events.DocumentEndEvent(start_mark, end_mark, explicit);
|
|
this.state = 'parse_document_start';
|
|
return event;
|
|
};
|
|
|
|
Parser.prototype.parse_document_content = function() {
|
|
var event;
|
|
|
|
if (this.check_token(tokens.DirectiveToken, tokens.DocumentStartToken, tokens.DocumentEndToken, tokens.StreamEndToken)) {
|
|
event = this.process_empty_scalar(this.peek_token().start_mark);
|
|
this.state = this.states.pop();
|
|
return event;
|
|
} else {
|
|
return this.parse_block_node();
|
|
}
|
|
};
|
|
|
|
Parser.prototype.process_directives = function() {
|
|
var handle, major, minor, prefix, tag_handles_copy, token, value, _ref1, _ref2, _ref3;
|
|
|
|
this.yaml_version = null;
|
|
this.tag_handles = {};
|
|
while (this.check_token(tokens.DirectiveToken)) {
|
|
token = this.get_token();
|
|
if (token.name === 'YAML') {
|
|
if (this.yaml_version !== null) {
|
|
throw new exports.ParserError(null, null, 'found duplicate YAML directive', token.start_mark);
|
|
}
|
|
_ref1 = token.value, major = _ref1[0], minor = _ref1[1];
|
|
if (major !== 1) {
|
|
throw new exports.ParserError(null, null, 'found incompatible YAML document (version 1.* is required)', token.start_mark);
|
|
}
|
|
this.yaml_version = token.value;
|
|
} else if (token.name === 'TAG') {
|
|
_ref2 = this.tag_handles, handle = _ref2[0], prefix = _ref2[1];
|
|
if (handle in this.tag_handles) {
|
|
throw new exports.ParserError(null, null, "duplicate tag handle " + handle, token.start_mark);
|
|
}
|
|
this.tag_handles[handle] = prefix;
|
|
}
|
|
}
|
|
tag_handles_copy = null;
|
|
_ref3 = this.tag_handles;
|
|
for (handle in _ref3) {
|
|
if (!__hasProp.call(_ref3, handle)) continue;
|
|
prefix = _ref3[handle];
|
|
if (tag_handles_copy == null) {
|
|
tag_handles_copy = {};
|
|
}
|
|
tag_handles_copy[handle] = prefix;
|
|
}
|
|
value = [this.yaml_version, tag_handles_copy];
|
|
for (handle in DEFAULT_TAGS) {
|
|
if (!__hasProp.call(DEFAULT_TAGS, handle)) continue;
|
|
prefix = DEFAULT_TAGS[handle];
|
|
if (!(prefix in this.tag_handles)) {
|
|
this.tag_handles[handle] = prefix;
|
|
}
|
|
}
|
|
return value;
|
|
};
|
|
|
|
Parser.prototype.parse_block_node = function() {
|
|
return this.parse_node(true);
|
|
};
|
|
|
|
Parser.prototype.parse_flow_node = function() {
|
|
return this.parse_node();
|
|
};
|
|
|
|
Parser.prototype.parse_block_node_or_indentless_sequence = function() {
|
|
return this.parse_node(true, true);
|
|
};
|
|
|
|
Parser.prototype.parse_node = function(block, indentless_sequence) {
|
|
var anchor, end_mark, event, handle, implicit, node, start_mark, suffix, tag, tag_mark, token;
|
|
|
|
if (block == null) {
|
|
block = false;
|
|
}
|
|
if (indentless_sequence == null) {
|
|
indentless_sequence = false;
|
|
}
|
|
if (this.check_token(tokens.AliasToken)) {
|
|
token = this.get_token();
|
|
event = new events.AliasEvent(token.value, token.start_mark, token.end_mark);
|
|
this.state = this.states.pop();
|
|
} else {
|
|
anchor = null;
|
|
tag = null;
|
|
start_mark = end_mark = tag_mark = null;
|
|
if (this.check_token(tokens.AnchorToken)) {
|
|
token = this.get_token();
|
|
start_mark = token.start_mark;
|
|
end_mark = token.end_mark;
|
|
anchor = token.value;
|
|
if (this.check_token(tokens.TagToken)) {
|
|
token = this.get_token();
|
|
tag_mark = token.start_mark;
|
|
end_mark = token.end_mark;
|
|
tag = token.value;
|
|
}
|
|
} else if (this.check_token(tokens.TagToken)) {
|
|
token = this.get_token();
|
|
start_mark = tag_mark = token.start_mark;
|
|
end_mark = token.end_mark;
|
|
tag = token.value;
|
|
if (this.check_token(tokens.AnchorToken)) {
|
|
token = this.get_token();
|
|
end_mark = token.end_mark;
|
|
anchor = token.value;
|
|
}
|
|
}
|
|
if (tag !== null) {
|
|
handle = tag[0], suffix = tag[1];
|
|
if (handle !== null) {
|
|
if (!(handle in this.tag_handles)) {
|
|
throw new exports.ParserError('while parsing a node', start_mark, "found undefined tag handle " + handle, tag_mark);
|
|
}
|
|
tag = this.tag_handles[handle] + suffix;
|
|
} else {
|
|
tag = suffix;
|
|
}
|
|
}
|
|
if (start_mark === null) {
|
|
start_mark = end_mark = this.peek_token().start_mark;
|
|
}
|
|
event = null;
|
|
implicit = tag === null || tag === '!';
|
|
if (indentless_sequence && this.check_token(tokens.BlockEntryToken)) {
|
|
end_mark = this.peek_token().end_mark;
|
|
event = new events.SequenceStartEvent(anchor, tag, implicit, start_mark, end_mark);
|
|
this.state = 'parse_indentless_sequence_entry';
|
|
} else {
|
|
if (this.check_token(tokens.ScalarToken)) {
|
|
token = this.get_token();
|
|
end_mark = token.end_mark;
|
|
if ((token.plain && tag === null) || tag === '!') {
|
|
implicit = [true, false];
|
|
} else if (tag === null) {
|
|
implicit = [false, true];
|
|
} else {
|
|
implicit = [false, false];
|
|
}
|
|
event = new events.ScalarEvent(anchor, tag, implicit, token.value, start_mark, end_mark, token.style);
|
|
this.state = this.states.pop();
|
|
} else if (this.check_token(tokens.FlowSequenceStartToken)) {
|
|
end_mark = this.peek_token().end_mark;
|
|
event = new events.SequenceStartEvent(anchor, tag, implicit, start_mark, end_mark, true);
|
|
this.state = 'parse_flow_sequence_first_entry';
|
|
} else if (this.check_token(tokens.FlowMappingStartToken)) {
|
|
end_mark = this.peek_token().end_mark;
|
|
event = new events.MappingStartEvent(anchor, tag, implicit, start_mark, end_mark, true);
|
|
this.state = 'parse_flow_mapping_first_key';
|
|
} else if (block && this.check_token(tokens.BlockSequenceStartToken)) {
|
|
end_mark = this.peek_token().end_mark;
|
|
event = new events.SequenceStartEvent(anchor, tag, implicit, start_mark, end_mark, false);
|
|
this.state = 'parse_block_sequence_first_entry';
|
|
} else if (block && this.check_token(tokens.BlockMappingStartToken)) {
|
|
end_mark = this.peek_token().end_mark;
|
|
event = new events.MappingStartEvent(anchor, tag, implicit, start_mark, end_mark, false);
|
|
this.state = 'parse_block_mapping_first_key';
|
|
} else if (anchor !== null || tag !== null) {
|
|
event = new events.ScalarEvent(anchor, tag, [implicit, false], '', start_mark, end_mark);
|
|
this.state = this.states.pop();
|
|
} else {
|
|
if (block) {
|
|
node = 'block';
|
|
} else {
|
|
node = 'flow';
|
|
}
|
|
token = this.peek_token();
|
|
throw new exports.ParserError("while parsing a " + node + " node", start_mark, "expected the node content, but found " + token.id, token.start_mark);
|
|
}
|
|
}
|
|
}
|
|
return event;
|
|
};
|
|
|
|
Parser.prototype.parse_block_sequence_first_entry = function() {
|
|
var token;
|
|
|
|
token = this.get_token();
|
|
this.marks.push(token.start_mark);
|
|
return this.parse_block_sequence_entry();
|
|
};
|
|
|
|
Parser.prototype.parse_block_sequence_entry = function() {
|
|
var event, token;
|
|
|
|
if (this.check_token(tokens.BlockEntryToken)) {
|
|
token = this.get_token();
|
|
if (!this.check_token(tokens.BlockEntryToken, tokens.BlockEndToken)) {
|
|
this.states.push('parse_block_sequence_entry');
|
|
return this.parse_block_node();
|
|
} else {
|
|
this.state = 'parse_block_sequence_entry';
|
|
return this.process_empty_scalar(token.end_mark);
|
|
}
|
|
}
|
|
if (!this.check_token(tokens.BlockEndToken)) {
|
|
token = this.peek_token();
|
|
throw new exports.ParserError('while parsing a block collection', this.marks.slice(-1)[0], "expected <block end>, but found " + token.id, token.start_mark);
|
|
}
|
|
token = this.get_token();
|
|
event = new events.SequenceEndEvent(token.start_mark, token.end_mark);
|
|
this.state = this.states.pop();
|
|
this.marks.pop();
|
|
return event;
|
|
};
|
|
|
|
Parser.prototype.parse_indentless_sequence_entry = function() {
|
|
var event, token;
|
|
|
|
if (this.check_token(tokens.BlockEntryToken)) {
|
|
token = this.get_token();
|
|
if (!this.check_token(tokens.BlockEntryToken, tokens.KeyToken, tokens.ValueToken, tokens.BlockEndToken)) {
|
|
this.states.push('parse_indentless_sequence_entry');
|
|
return this.parse_block_node();
|
|
} else {
|
|
this.state = 'parse_indentless_sequence_entry';
|
|
return this.process_empty_scalar(token.end_mark);
|
|
}
|
|
}
|
|
token = this.peek_token();
|
|
event = new events.SequenceEndEvent(token.start_mark, token.start_mark);
|
|
this.state = this.states.pop();
|
|
return event;
|
|
};
|
|
|
|
Parser.prototype.parse_block_mapping_first_key = function() {
|
|
var token;
|
|
|
|
token = this.get_token();
|
|
this.marks.push(token.start_mark);
|
|
return this.parse_block_mapping_key();
|
|
};
|
|
|
|
Parser.prototype.parse_block_mapping_key = function() {
|
|
var event, token;
|
|
|
|
if (this.check_token(tokens.KeyToken)) {
|
|
token = this.get_token();
|
|
if (!this.check_token(tokens.KeyToken, tokens.ValueToken, tokens.BlockEndToken)) {
|
|
this.states.push('parse_block_mapping_value');
|
|
return this.parse_block_node_or_indentless_sequence();
|
|
} else {
|
|
this.state = 'parse_block_mapping_value';
|
|
return this.process_empty_scalar(token.end_mark);
|
|
}
|
|
}
|
|
if (!this.check_token(tokens.BlockEndToken)) {
|
|
token = this.peek_token();
|
|
throw new exports.ParserError('while parsing a block mapping', this.marks.slice(-1)[0], "expected <block end>, but found " + token.id, token.start_mark);
|
|
}
|
|
token = this.get_token();
|
|
event = new events.MappingEndEvent(token.start_mark, token.end_mark);
|
|
this.state = this.states.pop();
|
|
this.marks.pop();
|
|
return event;
|
|
};
|
|
|
|
Parser.prototype.parse_block_mapping_value = function() {
|
|
var token;
|
|
|
|
if (this.check_token(tokens.ValueToken)) {
|
|
token = this.get_token();
|
|
if (!this.check_token(tokens.KeyToken, tokens.ValueToken, tokens.BlockEndToken)) {
|
|
this.states.push('parse_block_mapping_key');
|
|
return this.parse_block_node_or_indentless_sequence();
|
|
} else {
|
|
this.state = 'parse_block_mapping_key';
|
|
return this.process_empty_scalar(token.end_mark);
|
|
}
|
|
} else {
|
|
this.state = 'parse_block_mapping_key';
|
|
token = this.peek_token();
|
|
return this.process_empty_scalar(token.start_mark);
|
|
}
|
|
};
|
|
|
|
Parser.prototype.parse_flow_sequence_first_entry = function() {
|
|
var token;
|
|
|
|
token = this.get_token();
|
|
this.marks.push(token.start_mark);
|
|
return this.parse_flow_sequence_entry(true);
|
|
};
|
|
|
|
Parser.prototype.parse_flow_sequence_entry = function(first) {
|
|
var event, token;
|
|
|
|
if (first == null) {
|
|
first = false;
|
|
}
|
|
if (!this.check_token(tokens.FlowSequenceEndToken)) {
|
|
if (!first) {
|
|
if (this.check_token(tokens.FlowEntryToken)) {
|
|
this.get_token();
|
|
} else {
|
|
token = this.peek_token();
|
|
throw new exports.ParserError('while parsing a flow sequence', this.marks.slice(-1)[0], "expected ',' or ']', but got " + token.id, token.start_mark);
|
|
}
|
|
}
|
|
if (this.check_token(tokens.KeyToken)) {
|
|
token = this.peek_token();
|
|
event = new events.MappingStartEvent(null, null, true, token.start_mark, token.end_mark, true);
|
|
this.state = 'parse_flow_sequence_entry_mapping_key';
|
|
return event;
|
|
} else if (!this.check_token(tokens.FlowSequenceEndToken)) {
|
|
this.states.push('parse_flow_sequence_entry');
|
|
return this.parse_flow_node();
|
|
}
|
|
}
|
|
token = this.get_token();
|
|
event = new events.SequenceEndEvent(token.start_mark, token.end_mark);
|
|
this.state = this.states.pop();
|
|
this.marks.pop();
|
|
return event;
|
|
};
|
|
|
|
Parser.prototype.parse_flow_sequence_entry_mapping_key = function() {
|
|
var token;
|
|
|
|
token = this.get_token();
|
|
if (!this.check_token(tokens.ValueToken, tokens.FlowEntryToken, tokens.FlowSequenceEndToken)) {
|
|
this.states.push('parse_flow_sequence_entry_mapping_value');
|
|
return this.parse_flow_node();
|
|
} else {
|
|
this.state = 'parse_flow_sequence_entry_mapping_value';
|
|
return this.process_empty_scalar(token.end_mark);
|
|
}
|
|
};
|
|
|
|
Parser.prototype.parse_flow_sequence_entry_mapping_value = function() {
|
|
var token;
|
|
|
|
if (this.check_token(tokens.ValueToken)) {
|
|
token = this.get_token();
|
|
if (!this.check_token(tokens.FlowEntryToken, tokens.FlowSequenceEndToken)) {
|
|
this.states.push('parse_flow_sequence_entry_mapping_end');
|
|
return this.parse_flow_node();
|
|
} else {
|
|
this.state = 'parse_flow_sequence_entry_mapping_end';
|
|
return this.process_empty_scalar(token.end_mark);
|
|
}
|
|
} else {
|
|
this.state = 'parse_flow_sequence_entry_mapping_end';
|
|
token = this.peek_token();
|
|
return this.process_empty_scalar(token.start_mark);
|
|
}
|
|
};
|
|
|
|
Parser.prototype.parse_flow_sequence_entry_mapping_end = function() {
|
|
var token;
|
|
|
|
this.state = 'parse_flow_sequence_entry';
|
|
token = this.peek_token();
|
|
return new events.MappingEndEvent(token.start_mark, token.start_mark);
|
|
};
|
|
|
|
Parser.prototype.parse_flow_mapping_first_key = function() {
|
|
var token;
|
|
|
|
token = this.get_token();
|
|
this.marks.push(token.start_mark);
|
|
return this.parse_flow_mapping_key(true);
|
|
};
|
|
|
|
Parser.prototype.parse_flow_mapping_key = function(first) {
|
|
var event, token;
|
|
|
|
if (first == null) {
|
|
first = false;
|
|
}
|
|
if (!this.check_token(tokens.FlowMappingEndToken)) {
|
|
if (!first) {
|
|
if (this.check_token(tokens.FlowEntryToken)) {
|
|
this.get_token();
|
|
} else {
|
|
token = this.peek_token();
|
|
throw new exports.ParserError('while parsing a flow mapping', this.marks.slice(-1)[0], "expected ',' or '}', but got " + token.id, token.start_mark);
|
|
}
|
|
}
|
|
if (this.check_token(tokens.KeyToken)) {
|
|
token = this.get_token();
|
|
if (!this.check_token(tokens.ValueToken, tokens.FlowEntryToken, tokens.FlowMappingEndToken)) {
|
|
this.states.push('parse_flow_mapping_value');
|
|
return this.parse_flow_node();
|
|
} else {
|
|
this.state = 'parse_flow_mapping_value';
|
|
return this.process_empty_scalar(token.end_mark);
|
|
}
|
|
} else if (!this.check_token(tokens.FlowMappingEndToken)) {
|
|
this.states.push('parse_flow_mapping_empty_value');
|
|
return this.parse_flow_node();
|
|
}
|
|
}
|
|
token = this.get_token();
|
|
event = new events.MappingEndEvent(token.start_mark, token.end_mark);
|
|
this.state = this.states.pop();
|
|
this.marks.pop();
|
|
return event;
|
|
};
|
|
|
|
Parser.prototype.parse_flow_mapping_value = function() {
|
|
var token;
|
|
|
|
if (this.check_token(tokens.ValueToken)) {
|
|
token = this.get_token();
|
|
if (!this.check_token(tokens.FlowEntryToken, tokens.FlowMappingEndToken)) {
|
|
this.states.push('parse_flow_mapping_key');
|
|
return this.parse_flow_node();
|
|
} else {
|
|
this.state = 'parse_flow_mapping_key';
|
|
return this.process_empty_scalar(token.end_mark);
|
|
}
|
|
} else {
|
|
this.state = 'parse_flow_mapping_key';
|
|
token = this.peek_token();
|
|
return this.process_empty_scalar(token.start_mark);
|
|
}
|
|
};
|
|
|
|
Parser.prototype.parse_flow_mapping_empty_value = function() {
|
|
this.state = 'parse_flow_mapping_key';
|
|
return this.process_empty_scalar(this.peek_token().start_mark);
|
|
};
|
|
|
|
Parser.prototype.process_empty_scalar = function(mark) {
|
|
return new events.ScalarEvent(null, null, [true, false], '', mark, mark);
|
|
};
|
|
|
|
return Parser;
|
|
|
|
})();
|
|
|
|
}).call(this);
|