public class ParserImpl extends java.lang.Object implements Parser
# The following YAML grammar is LL(1) and is parsed by a recursive descent parser. stream ::= STREAM-START implicit_document? explicit_document* STREAM-END implicit_document ::= block_node DOCUMENT-END* explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* block_node_or_indentless_sequence ::= ALIAS | properties (block_content | indentless_block_sequence)? | block_content | indentless_block_sequence block_node ::= ALIAS | properties block_content? | block_content flow_node ::= ALIAS | properties flow_content? | flow_content properties ::= TAG ANCHOR? | ANCHOR TAG? block_content ::= block_collection | flow_collection | SCALAR flow_content ::= flow_collection | SCALAR block_collection ::= block_sequence | block_mapping flow_collection ::= flow_sequence | flow_mapping block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END indentless_sequence ::= (BLOCK-ENTRY block_node?)+ block_mapping ::= BLOCK-MAPPING_START ((KEY block_node_or_indentless_sequence?)? (VALUE block_node_or_indentless_sequence?)?)* BLOCK-END flow_sequence ::= FLOW-SEQUENCE-START (flow_sequence_entry FLOW-ENTRY)* flow_sequence_entry? FLOW-SEQUENCE-END flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? flow_mapping ::= FLOW-MAPPING-START (flow_mapping_entry FLOW-ENTRY)* flow_mapping_entry? FLOW-MAPPING-END flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? FIRST sets: stream: { STREAM-START } explicit_document: { DIRECTIVE DOCUMENT-START } implicit_document: FIRST(block_node) block_node: { ALIAS TAG ANCHOR SCALAR BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START } flow_node: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START } block_content: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR } flow_content: { FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR } block_collection: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START } flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START } block_sequence: { BLOCK-SEQUENCE-START } block_mapping: { BLOCK-MAPPING-START } block_node_or_indentless_sequence: { ALIAS ANCHOR TAG SCALAR BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START BLOCK-ENTRY } indentless_sequence: { ENTRY } flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START } flow_sequence: { FLOW-SEQUENCE-START } flow_mapping: { FLOW-MAPPING-START } flow_sequence_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START KEY } flow_mapping_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START KEY }Since writing a recursive-descendant parser is a straightforward task, we do not give many comments here.
Modifier and Type | Class and Description |
---|---|
private class |
ParserImpl.ParseBlockMappingFirstKey |
private class |
ParserImpl.ParseBlockMappingKey |
private class |
ParserImpl.ParseBlockMappingValue |
private class |
ParserImpl.ParseBlockMappingValueComment |
private class |
ParserImpl.ParseBlockMappingValueCommentList |
private class |
ParserImpl.ParseBlockNode
block_node_or_indentless_sequence ::= ALIAS
| properties (block_content | indentless_block_sequence)?
| block_content
| indentless_block_sequence
block_node ::= ALIAS
| properties block_content?
| block_content
flow_node ::= ALIAS
| properties flow_content?
| flow_content
properties ::= TAG ANCHOR? | ANCHOR TAG?
block_content ::= block_collection | flow_collection | SCALAR
flow_content ::= flow_collection | SCALAR
block_collection ::= block_sequence | block_mapping
flow_collection ::= flow_sequence | flow_mapping
|
private class |
ParserImpl.ParseBlockSequenceEntryKey |
private class |
ParserImpl.ParseBlockSequenceEntryValue |
private class |
ParserImpl.ParseBlockSequenceFirstEntry |
private class |
ParserImpl.ParseDocumentContent |
private class |
ParserImpl.ParseDocumentEnd |
private class |
ParserImpl.ParseDocumentStart |
private class |
ParserImpl.ParseFlowEndComment |
private class |
ParserImpl.ParseFlowMappingEmptyValue |
private class |
ParserImpl.ParseFlowMappingFirstKey
flow_mapping ::= FLOW-MAPPING-START
(flow_mapping_entry FLOW-ENTRY)*
flow_mapping_entry?
FLOW-MAPPING-END
flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
|
private class |
ParserImpl.ParseFlowMappingKey |
private class |
ParserImpl.ParseFlowMappingValue |
private class |
ParserImpl.ParseFlowSequenceEntry |
private class |
ParserImpl.ParseFlowSequenceEntryMappingEnd |
private class |
ParserImpl.ParseFlowSequenceEntryMappingKey |
private class |
ParserImpl.ParseFlowSequenceEntryMappingValue |
private class |
ParserImpl.ParseFlowSequenceFirstEntry
flow_sequence ::= FLOW-SEQUENCE-START
(flow_sequence_entry FLOW-ENTRY)*
flow_sequence_entry?
FLOW-SEQUENCE-END
flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
Note that while production rules for both flow_sequence_entry and
flow_mapping_entry are equal, their interpretations are different.
|
private class |
ParserImpl.ParseImplicitDocumentStart |
private class |
ParserImpl.ParseIndentlessSequenceEntryKey |
private class |
ParserImpl.ParseIndentlessSequenceEntryValue |
private class |
ParserImpl.ParseStreamStart
stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
implicit_document ::= block_node DOCUMENT-END*
explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
|
Modifier and Type | Field and Description |
---|---|
private Event |
currentEvent |
private static java.util.Map<java.lang.String,java.lang.String> |
DEFAULT_TAGS |
private VersionTagsTuple |
directives |
private ArrayStack<Mark> |
marks |
protected Scanner |
scanner |
private Production |
state |
private ArrayStack<Production> |
states |
Constructor and Description |
---|
ParserImpl(Scanner scanner) |
ParserImpl(StreamReader reader) |
ParserImpl(StreamReader reader,
boolean parseComments)
Deprecated.
|
ParserImpl(StreamReader reader,
LoaderOptions options) |
Modifier and Type | Method and Description |
---|---|
boolean |
checkEvent(Event.ID choice)
Check the type of the next event.
|
Event |
getEvent()
Get the next event and proceed further.
|
private Event |
parseBlockNodeOrIndentlessSequence() |
private Event |
parseFlowNode() |
private Event |
parseNode(boolean block,
boolean indentlessSequence) |
Event |
peekEvent()
Get the next event.
|
private VersionTagsTuple |
processDirectives()
https://yaml.org/spec/1.1/#id898785 says "If the document specifies no directives, it is parsed
using the same settings as the previous document.
|
private Event |
processEmptyScalar(Mark mark)
block_mapping ::= BLOCK-MAPPING_START
((KEY block_node_or_indentless_sequence?)?
(VALUE block_node_or_indentless_sequence?)?)*
BLOCK-END
|
private CommentEvent |
produceCommentEvent(CommentToken token) |
private static final java.util.Map<java.lang.String,java.lang.String> DEFAULT_TAGS
protected final Scanner scanner
private Event currentEvent
private final ArrayStack<Production> states
private final ArrayStack<Mark> marks
private Production state
private VersionTagsTuple directives
public ParserImpl(StreamReader reader)
@Deprecated public ParserImpl(StreamReader reader, boolean parseComments)
public ParserImpl(StreamReader reader, LoaderOptions options)
public ParserImpl(Scanner scanner)
public boolean checkEvent(Event.ID choice)
checkEvent
in interface Parser
choice
- Event ID.true
if the next event can be assigned to a variable of the given type.
Returns false
if no more events are available.public Event peekEvent()
peekEvent
in interface Parser
Parser.getEvent()
public Event getEvent()
private CommentEvent produceCommentEvent(CommentToken token)
private VersionTagsTuple processDirectives()
private Event parseFlowNode()
private Event parseBlockNodeOrIndentlessSequence()
private Event parseNode(boolean block, boolean indentlessSequence)