Class: Psych::Pure::Parser
- Inherits:
-
StringScanner
- Object
- StringScanner
- Psych::Pure::Parser
- Defined in:
- lib/psych/pure.rb
Overview
The parser is responsible for taking a YAML string and converting it into a series of events that can be used by the consumer.
Defined Under Namespace
Instance Method Summary collapse
-
#initialize(handler) ⇒ Parser
constructor
Initialize a new parser with the given source string.
-
#parse(yaml, filename = yaml.respond_to?(:path) ? yaml.path : "<unknown>", comments: false) ⇒ Object
Top-level parse function that starts the parsing process.
Constructor Details
#initialize(handler) ⇒ Parser
Initialize a new parser with the given source string.
1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 |
# File 'lib/psych/pure.rb', line 1029 def initialize(handler) super("") # These are used to track the current state of the parser. @filename = nil @source = nil # The handler is the consumer of the events generated by the parser. @handler = handler # This functions as a list of temporary lists of events that may be # flushed into the handler if current context is matched. @events_cache = [] @events_cache_marks = [] @events_cache_depth = 0 # Document start/end state. These are deferred and flushed lazily — # the document start is emitted when the first content event arrives, # and the document end is emitted when the next document starts. @doc_start_pos = nil @doc_start_version = nil @doc_start_implicit = true @doc_end_pos = nil @doc_end_implicit = true # Each document gets its own set of tags. This is a mapping of tag # handles to tag prefixes. @tag_directives = nil # When a tag property is parsed, it is stored here until it can be # flushed into the next event. @tag = nil # When a tag handle is parsed, it is stored here until the tag prefix # is parsed and the full tag can be resolved. @tag_handle = nil # When an anchor is parsed, it is stored here until it can be flushed # into the next event. @anchor = nil # In a bare document, explicit document starts (---) and ends (...) are # disallowed. In that case we need to check for those delimiters. = false @check_forbidden = false # In a literal or folded scalar, we need to track that state in order to # insert the correct plain text prefix. @in_scalar = false @text_prefix = +"" # This parser can optionally parse comments and attach them to the # resulting tree, if the option is passed. @comments = nil # The context of the parser at any given time, which is used to decorate # error messages to make it easier to find the specific location where # they occurred. @context = Context.new end |
Instance Method Details
#parse(yaml, filename = yaml.respond_to?(:path) ? yaml.path : "<unknown>", comments: false) ⇒ Object
Top-level parse function that starts the parsing process.
1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 |
# File 'lib/psych/pure.rb', line 1091 def parse(yaml, filename = yaml.respond_to?(:path) ? yaml.path : "<unknown>", comments: false) if yaml.respond_to?(:read) yaml = yaml.read elsif !yaml.is_a?(String) raise TypeError, "Expected an IO or a String, got #{yaml.class}" end # This parser only supports UTF-8 encoding at the moment. This is # largely due to the performance impact of having to convert all of the # strings and regular expressions into compatible encodings. We do not # attempt to transcode, as the locations would all be off at that point. if yaml.encoding != Encoding::UTF_8 raise ArgumentError, "Expected UTF-8 encoding, got #{yaml.encoding}" end yaml += "\n" if !yaml.empty? && !yaml.end_with?("\n") # Set StringScanner's source (used by skip/match/eos?) and keep a # direct reference for raw byte access (getbyte/byteslice) which # bypasses StringScanner for performance-critical paths. self.string = yaml @string = yaml @filename = filename @source = Source.new(yaml) @comments = {} if comments # Precompute positions where --- or ... appear at start of a line # followed by whitespace or end of string. These are forbidden content # positions in bare documents. @forbidden_content = {} yaml.scan(/^(?:---|\.\.\.)(?=[\s]|\z)/m) { @forbidden_content[$~.begin(0)] = true } @has_forbidden_content = !@forbidden_content.empty? parse_l_yaml_stream @comments = nil if comments true end |