123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294 |
- 'use strict';
- var fs = require('fs'),
- assert = require('assert'),
- jsyaml = require(__dirname + '/../../lib/js-yaml'),
- helper = require(__dirname + '/../test-helper'),
- $$ = require(__dirname + '/../../lib/js-yaml/common'),
- _errors = require(__dirname + '/../../lib/js-yaml/errors'),
- _composer = require(__dirname + '/../../lib/js-yaml/composer'),
- _constructor = require(__dirname + '/../../lib/js-yaml/construct'),
- _tokens = require(__dirname + '/../../lib/js-yaml/tokens'),
- _resolver = require(__dirname + '/../../lib/js-yaml/resolver');
- var DIRECTIVE = '%YAML 1.1';
- var QUOTE_CODES = {
- 'x': 2,
- 'u': 4,
- 'U': 8
- };
- var QUOTE_REPLACES = {
- '\\': '\\',
- '\"': '\"',
- ' ': ' ',
- 'a': '\x07',
- 'b': '\x08',
- 'e': '\x1B',
- 'f': '\x0C',
- 'n': '\x0A',
- 'r': '\x0D',
- 't': '\x09',
- 'v': '\x0B',
- 'N': '\u0085',
- 'L': '\u2028',
- 'P': '\u2029',
- '_': '_',
- '0': '\x00'
- };
- function CanonicalError() {
- _errors.YAMLError.apply(this, arguments);
- this.name = 'CanonicalError';
- }
- $$.inherits(CanonicalError, _errors.YAMLError);
- function CanonicalScanner(data) {
- this.data = data + '\x00';
- this.index = 0;
- this.tokens = [];
- this.scanned = false;
- }
- CanonicalScanner.prototype.checkToken = function checkTokencheckToken() {
- var i;
- if (!this.scanned) {
- this.scan();
- }
- if (this.tokens.length) {
- if (!arguments.length) {
- return true;
- }
- for (i = 0; i < arguments.length; i += 1) {
- if (this.tokens[0].isA(arguments[i])) {
- return true;
- }
- }
- }
- return false;
- };
- CanonicalScanner.prototype.peekToken = function peekToken() {
- if (!this.scanned) {
- this.scan();
- }
- if (this.tokens.length) {
- return this.tokens[0];
- }
- return null;
- };
- CanonicalScanner.prototype.getToken = function getToken(choice) {
- var token = null;
- if (!this.scanned) {
- this.scan();
- }
- token = this.tokens.shift();
- if (choice && !token.isA(choice)) {
- throw new CanonicalError("unexpected token " + token.hash());
- }
- return token;
- };
- CanonicalScanner.prototype.scan = function scan() {
- var ch;
- this.tokens.push(new _tokens.StreamStartToken(null, null));
- while (true) {
- this.find_token();
- ch = this.data[this.index];
- if (ch === '\x00') {
- this.tokens.push(new _tokens.StreamEndToken(null, null));
- break;
- } else if (ch === '%') {
- this.tokens.push(this.scanDirective());
- } else if (ch === '-' && this.data.silce(this.index, this.index+3) === '---') {
- this.index += 3;
- this.tokens.push(new _tokens.DocumentStartToken(null, null));
- } else if (ch === '[') {
- this.index += 1;
- this.tokens.push(new _tokens.FlowSequenceStartToken(null, null));
- } else if (ch === '{') {
- this.index += 1;
- this.tokens.push(new _tokens.FlowMappingStartToken(null, null));
- } else if (ch === ']') {
- this.index += 1;
- this.tokens.push(new _tokens.FlowSequenceEndToken(null, null));
- } else if (ch === '}') {
- this.index += 1;
- this.tokens.push(new _tokens.FlowMappingEndToken(null, null));
- } else if (ch === '?') {
- this.index += 1;
- this.tokens.push(new _tokens.KeyToken(null, null));
- } else if (ch === ':') {
- this.index += 1;
- this.tokens.push(new _tokens.ValueToken(null, null));
- } else if (ch === ',') {
- this.index += 1;
- this.tokens.push(new _tokens.FlowEntryToken(null, null));
- } else if (ch === '*' || ch === '&') {
- this.tokens.push(this.scanAlias());
- } else if (ch === '!') {
- this.tokens.push(this.scanTag());
- } else if (ch === '"') {
- this.tokens.push(this.scanScalar());
- } else {
- throw new CanonicalError("invalid token");
- }
- }
- this.scanned = true;
- };
- CanonicalScanner.prototype.scanDirective = function scanDirective() {
- if (this.data.slice(this.index, this.index + DIRECTIVE.length) === this.DIRECTIVE
- && 0 <= ' \n\x00'.indexOf(this.data.slice(this.index + DIRECTIVE.length))) {
- this.index += this.DIRECTIVE.length;
- return new _tokens.DirectiveToken('YAML', [1, 1], null, null);
- }
- throw new CanonicalError("invalid directive");
- };
- CanonicalScanner.prototype.scanAlias = function scanAlias() {
- var start, value, TokenClass;
- TokenClass = (this.data[this.index] === '*')
- ? (_tokens.AliasToken) : (_tokens.AnchorToken);
- this.index += 1;
- start = this.index;
- while (-1 === ', \n\x00'.indexOf(this.data[this.index])) {
- this.index += 1;
- }
- value = this.data.slice(start, this.index);
- return new TokenClass(value, null, null);
- };
- CanonicalScanner.prototype.scanTag = function scanTag() {
- var start, value;
- this.index += 1;
- start = this.index;
- while (-1 === ' \n\x00'.indexOf(this.data[this.index])) {
- this.index += 1;
- }
- value = this.data.slice(start, this.index);
- if (!value) {
- value = '!';
- } else if (value[0] === '!') {
- value = 'tag:yaml.org,2002:' + value.slice(1);
- } else if (value[0] === '<' && value[value.length-1] === '>') {
- value = value.slice(1, value.length-2);
- } else {
- value = '!' + value;
- }
- return new _tokens.TagToken(value, null, null);
- };
- CanonicalScanner.prototype.scanScalar = function scanScalar() {
- var chunks, start, ignoreSpaces, ch, code, length;
- this.index += 1;
- chunks = [];
- start = this.index;
- ignoreSpaces = false;
- while (this.data[this.index] !== '"') {
- if (this.data[this.index] === '\\') {
- ignoreSpaces = false;
- chunks.push(this.data.slice(start, this.index));
- this.index += 1;
- ch = this.data[this.index];
- this.index += 1;
- if (ch === '\n') {
- ignoreSpaces = true;
- } else if (0 <= QUOTE_CODES.indexOf(ch)) {
- length = QUOTE_CODES[ch];
- code = parseInt(this.data.slice(this.index, this.index+length), 16);
- chunks.puush(String.fromCharCode(code));
- this.index += length;
- } else {
- if (-1 === QUOTE_REPLACES.indexOf(ch)) {
- throw new CanonicalError("invalid escape code");
- }
- chunks.push(QUOTE_REPLACES[ch]);
- }
- start = this.index;
- } else if (this.data[this.index] === '\n') {
- chunks.push(this.data.slice(start, this.index));
- chunks.push(' ');
- this.index += 1;
- start = this.index;
- ignoreSpaces = true;
- } else if (ignoreSpaces && this.data[this.index] === ' ') {
- this.index += 1;
- start = this.index;
- } else {
- ignoreSpaces = false;
- this.index += 1;
- }
- }
- chunks.push(this.data.slice(start, this.index));
- this.index += 1;
- return new _tokens.ScalarToken(chunks.join(''), false, null, null);
- };
- CanonicalScanner.prototype.findToken = function findToken() {
- var found = false;
- while (!found) {
- while (0 <= ' \t'.indexOf(this.data[this.index])) {
- this.index += 1;
- }
- if (this.data[this.index] === '#') {
- while (this.data[this.index] !== '\n') {
- this.index += 1;
- }
- }
- if (this.data[this.index] === '\n') {
- this.index += 1;
- } else {
- found = true;
- }
- }
- };
- module.exports.CanonicalScanner = CanonicalScanner;
- ////////////////////////////////////////////////////////////////////////////////
- // vim:ts=2:sw=2
- ////////////////////////////////////////////////////////////////////////////////
|