OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library parser; | 5 library yaml.parser; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import 'model.dart'; | 9 import 'model.dart'; |
10 import 'yaml_exception.dart'; | 10 import 'yaml_exception.dart'; |
11 import 'yaml_map.dart'; | 11 import 'yaml_map.dart'; |
12 | 12 |
13 /// Translates a string of characters into a YAML serialization tree. | 13 /// Translates a string of characters into a YAML serialization tree. |
14 /// | 14 /// |
15 /// This parser is designed to closely follow the spec. All productions in the | 15 /// This parser is designed to closely follow the spec. All productions in the |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 end = _pos; | 400 end = _pos; |
401 return false; | 401 return false; |
402 }); | 402 }); |
403 _errorAnnotations[new _Range(start, end)] = message; | 403 _errorAnnotations[new _Range(start, end)] = message; |
404 } | 404 } |
405 | 405 |
406 /// Throws an error with additional context information. | 406 /// Throws an error with additional context information. |
407 error(String message) { | 407 error(String message) { |
408 // Line and column should be one-based. | 408 // Line and column should be one-based. |
409 throw new SyntaxError(_line + 1, _column + 1, | 409 throw new SyntaxError(_line + 1, _column + 1, |
410 "$message (in $_farthestContext)"); | 410 "$message (in $_farthestContext)."); |
411 } | 411 } |
412 | 412 |
413 /// If [result] is falsey, throws an error saying that [expected] was | 413 /// If [result] is falsey, throws an error saying that [expected] was |
414 /// expected. | 414 /// expected. |
415 expect(result, String expected) { | 415 expect(result, String expected) { |
416 if (truth(result)) return result; | 416 if (truth(result)) return result; |
417 error("expected $expected"); | 417 error("Expected $expected"); |
418 } | 418 } |
419 | 419 |
420 /// Throws an error saying that the parse failed. Uses [_farthestLine], | 420 /// Throws an error saying that the parse failed. Uses [_farthestLine], |
421 /// [_farthestColumn], and [_farthestContext] to provide additional informatio
n. | 421 /// [_farthestColumn], and [_farthestContext] to provide additional |
| 422 /// information. |
422 parseFailed() { | 423 parseFailed() { |
423 var message = "invalid YAML in $_farthestContext"; | 424 var message = "Invalid YAML in $_farthestContext"; |
424 var extraError = _errorAnnotations[_farthestPos]; | 425 var extraError = _errorAnnotations[_farthestPos]; |
425 if (extraError != null) message = "$message ($extraError)"; | 426 if (extraError != null) message = "$message ($extraError)"; |
426 throw new SyntaxError(_farthestLine + 1, _farthestColumn + 1, message); | 427 throw new SyntaxError(_farthestLine + 1, _farthestColumn + 1, "$message."); |
427 } | 428 } |
428 | 429 |
429 /// Returns the number of spaces after the current position. | 430 /// Returns the number of spaces after the current position. |
430 int countIndentation() { | 431 int countIndentation() { |
431 var i = 0; | 432 var i = 0; |
432 while (peek(i) == SP) i++; | 433 while (peek(i) == SP) i++; |
433 return i; | 434 return i; |
434 } | 435 } |
435 | 436 |
436 /// Returns the indentation for a block scalar. | 437 /// Returns the indentation for a block scalar. |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
781 bool s_separate(int indent, int ctx) { | 782 bool s_separate(int indent, int ctx) { |
782 switch (ctx) { | 783 switch (ctx) { |
783 case BLOCK_OUT: | 784 case BLOCK_OUT: |
784 case BLOCK_IN: | 785 case BLOCK_IN: |
785 case FLOW_OUT: | 786 case FLOW_OUT: |
786 case FLOW_IN: | 787 case FLOW_IN: |
787 return s_separateLines(indent); | 788 return s_separateLines(indent); |
788 case BLOCK_KEY: | 789 case BLOCK_KEY: |
789 case FLOW_KEY: | 790 case FLOW_KEY: |
790 return s_separateInLine(); | 791 return s_separateInLine(); |
791 default: throw 'invalid context "$ctx"'; | 792 default: throw 'Invalid context "$ctx".'; |
792 } | 793 } |
793 } | 794 } |
794 | 795 |
795 // 81 | 796 // 81 |
796 bool s_separateLines(int indent) { | 797 bool s_separateLines(int indent) { |
797 return transaction(() => s_l_comments() && s_flowLinePrefix(indent)) || | 798 return transaction(() => s_l_comments() && s_flowLinePrefix(indent)) || |
798 s_separateInLine(); | 799 s_separateInLine(); |
799 } | 800 } |
800 | 801 |
801 // 82 | 802 // 82 |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1007 () => s_singleNextLine(indent), | 1008 () => s_singleNextLine(indent), |
1008 () => zeroOrMore(() => consume(isSpace)) | 1009 () => zeroOrMore(() => consume(isSpace)) |
1009 ]); | 1010 ]); |
1010 } | 1011 } |
1011 | 1012 |
1012 // 126 | 1013 // 126 |
1013 bool ns_plainFirst(int ctx) { | 1014 bool ns_plainFirst(int ctx) { |
1014 var char = peek(); | 1015 var char = peek(); |
1015 var indicator = indicatorType(char); | 1016 var indicator = indicatorType(char); |
1016 if (indicator == C_RESERVED) { | 1017 if (indicator == C_RESERVED) { |
1017 error("reserved indicators can't start a plain scalar"); | 1018 error("Reserved indicators can't start a plain scalar"); |
1018 } | 1019 } |
1019 var match = (isNonSpace(char) && indicator == null) || | 1020 var match = (isNonSpace(char) && indicator == null) || |
1020 ((indicator == C_MAPPING_KEY || | 1021 ((indicator == C_MAPPING_KEY || |
1021 indicator == C_MAPPING_VALUE || | 1022 indicator == C_MAPPING_VALUE || |
1022 indicator == C_SEQUENCE_ENTRY) && | 1023 indicator == C_SEQUENCE_ENTRY) && |
1023 isPlainSafe(ctx, peek(1))); | 1024 isPlainSafe(ctx, peek(1))); |
1024 | 1025 |
1025 if (match) next(); | 1026 if (match) next(); |
1026 return match; | 1027 return match; |
1027 } | 1028 } |
1028 | 1029 |
1029 // 127 | 1030 // 127 |
1030 bool isPlainSafe(int ctx, int char) { | 1031 bool isPlainSafe(int ctx, int char) { |
1031 switch (ctx) { | 1032 switch (ctx) { |
1032 case FLOW_OUT: | 1033 case FLOW_OUT: |
1033 case BLOCK_KEY: | 1034 case BLOCK_KEY: |
1034 // 128 | 1035 // 128 |
1035 return isNonSpace(char); | 1036 return isNonSpace(char); |
1036 case FLOW_IN: | 1037 case FLOW_IN: |
1037 case FLOW_KEY: | 1038 case FLOW_KEY: |
1038 // 129 | 1039 // 129 |
1039 return isNonSpace(char) && !isFlowIndicator(char); | 1040 return isNonSpace(char) && !isFlowIndicator(char); |
1040 default: throw 'invalid context "$ctx"'; | 1041 default: throw 'Invalid context "$ctx".'; |
1041 } | 1042 } |
1042 } | 1043 } |
1043 | 1044 |
1044 // 130 | 1045 // 130 |
1045 bool ns_plainChar(int ctx) { | 1046 bool ns_plainChar(int ctx) { |
1046 var char = peek(); | 1047 var char = peek(); |
1047 var indicator = indicatorType(char); | 1048 var indicator = indicatorType(char); |
1048 var safeChar = isPlainSafe(ctx, char) && indicator != C_MAPPING_VALUE && | 1049 var safeChar = isPlainSafe(ctx, char) && indicator != C_MAPPING_VALUE && |
1049 indicator != C_COMMENT; | 1050 indicator != C_COMMENT; |
1050 var nonCommentHash = isNonSpace(peek(-1)) && indicator == C_COMMENT; | 1051 var nonCommentHash = isNonSpace(peek(-1)) && indicator == C_COMMENT; |
1051 var nonMappingColon = indicator == C_MAPPING_VALUE && | 1052 var nonMappingColon = indicator == C_MAPPING_VALUE && |
1052 isPlainSafe(ctx, peek(1)); | 1053 isPlainSafe(ctx, peek(1)); |
1053 var match = safeChar || nonCommentHash || nonMappingColon; | 1054 var match = safeChar || nonCommentHash || nonMappingColon; |
1054 | 1055 |
1055 if (match) next(); | 1056 if (match) next(); |
1056 return match; | 1057 return match; |
1057 } | 1058 } |
1058 | 1059 |
1059 // 131 | 1060 // 131 |
1060 String ns_plain(int indent, int ctx) => context('plain scalar', () { | 1061 String ns_plain(int indent, int ctx) => context('plain scalar', () { |
1061 return captureString(() { | 1062 return captureString(() { |
1062 switch (ctx) { | 1063 switch (ctx) { |
1063 case FLOW_OUT: | 1064 case FLOW_OUT: |
1064 case FLOW_IN: | 1065 case FLOW_IN: |
1065 return ns_plainMultiLine(indent, ctx); | 1066 return ns_plainMultiLine(indent, ctx); |
1066 case BLOCK_KEY: | 1067 case BLOCK_KEY: |
1067 case FLOW_KEY: | 1068 case FLOW_KEY: |
1068 return ns_plainOneLine(ctx); | 1069 return ns_plainOneLine(ctx); |
1069 default: throw 'invalid context "$ctx"'; | 1070 default: throw 'Invalid context "$ctx".'; |
1070 } | 1071 } |
1071 }); | 1072 }); |
1072 }); | 1073 }); |
1073 | 1074 |
1074 // 132 | 1075 // 132 |
1075 void nb_ns_plainInLine(int ctx) { | 1076 void nb_ns_plainInLine(int ctx) { |
1076 zeroOrMore(() => transaction(() { | 1077 zeroOrMore(() => transaction(() { |
1077 zeroOrMore(() => consume(isSpace)); | 1078 zeroOrMore(() => consume(isSpace)); |
1078 return ns_plainChar(ctx); | 1079 return ns_plainChar(ctx); |
1079 })); | 1080 })); |
(...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1938 for (var pair in _contents.reversed) { | 1939 for (var pair in _contents.reversed) { |
1939 if (pair.first.contains(pos)) return pair.last; | 1940 if (pair.first.contains(pos)) return pair.last; |
1940 } | 1941 } |
1941 return null; | 1942 return null; |
1942 } | 1943 } |
1943 | 1944 |
1944 /// Associates [value] with [range]. | 1945 /// Associates [value] with [range]. |
1945 operator[]=(_Range range, E value) => | 1946 operator[]=(_Range range, E value) => |
1946 _contents.add(new _Pair<_Range, E>(range, value)); | 1947 _contents.add(new _Pair<_Range, E>(range, value)); |
1947 } | 1948 } |
OLD | NEW |