Module: Brandish::Parser::Main
- Included in:
- Brandish::Parser
- Defined in:
- lib/brandish/parser/main.rb
Overview
The main parser for the document. This constructs a tree of nodes that can be used to represent the original document.
Constant Summary collapse
- QUOTE_SYMBOL =
A set containing the kind symbol for a quote.
- EQUAL_SYMBOL =
A set containing the kind symbol for an equal sign.
- LESS_THAN_SYMBOL =
A set containing the kind symbol for a less than symbol.
- GREATER_THAN_SYMBOL =
A set containing the kind symbol for a greater than symbol.
- SLASH_SYMBOL =
A set containing the kind symbol for a forward slash symbol.
- SLASH_OR_GREATER_THAN_SYMBOL =
A set containing the kind symbols for a forward slash or a greater than symbol.
SLASH_SYMBOL | GREATER_THAN_SYMBOL
- TEXT_SYMBOL =
A set containing the kind symbols for a text symbol.
- SPACE_SYMBOLS =
A set containing the kind symbols for a space symbol.
- EOF_SYMBOL =
A set containing the kind symbols for a eof symbol.
Instance Method Summary collapse
-
#parse_document ⇒ Parser::Node
(also: #parse_root)
Parses the overall document.
-
#parse_document_block(start, name, arguments) ⇒ Node::Block
Parses a "block." This is similar to a HTML tag in the sense that it has a name and a body; however, blocks do not have any sort of arguments to them.
-
#parse_document_block_body ⇒ Node::Root
Parses the body of a block tag.
-
#parse_document_command(start, name, arguments) ⇒ Node::Command
Parses a document command.
-
#parse_document_command_argument ⇒ Node::Pair
Parses a document command argument.
-
#parse_document_command_argument_key ⇒ Scanner::Token
The key for the command argument.
-
#parse_document_command_argument_value ⇒ Node
The value for the command argument.
-
#parse_document_element ⇒ Node
Parses a single element in the docuemnt.
-
#parse_document_meta(start = expect(LESS_THAN_SYMBOL)) ⇒ Node
parses a "meta" element from the document.
-
#parse_document_string ⇒ Node::String
Parses a "string." This is a series of text encapulated by quotes.
-
#parse_document_text ⇒ Node::Text
Parses a document for text.
-
#parse_skip_space ⇒ void
Skips over nodes as long as they're space nodes.
Instance Method Details
#parse_document ⇒ Parser::Node Also known as: parse_root
Parses the overall document. This parses a sequence of
elements until it reaches the EOF
token.
14 15 16 17 18 |
# File 'lib/brandish/parser/main.rb', line 14 def parse_document body = collect(EOF_SYMBOL) { parse_document_element } expect(EOF_SYMBOL) Node::Root.new(children: body) end |
#parse_document_block(start, name, arguments) ⇒ Node::Block
Parses a "block." This is similar to a HTML tag in the sense that it has a name and a body; however, blocks do not have any sort of arguments to them.
block ::= '<' TEXT *command-argument '>' *element '</' TEXT '>'
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/brandish/parser/main.rb', line 118 def parse_document_block(start, name, arguments) expect(GREATER_THAN_SYMBOL) body = parse_document_block_body expect(SLASH_SYMBOL) match = expect(TEXT_SYMBOL) stop = expect(GREATER_THAN_SYMBOL) unless name.value == match.value fail ParseError.new("Unexpected #{match.value.inspect}, expected" \ " #{name.value.inspect}", match.location) end Node::Block.new(name: name, body: body, arguments: arguments, location: start.location.union(body.location, match.location, stop.location, *arguments.map(&:location))) end |
#parse_document_block_body ⇒ Node::Root
Parses the body of a block tag. This keeps attempting to parse text
and meta tags until it encounters the phrase </
, at which point it
will stop parsing and return to the parent.
140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/brandish/parser/main.rb', line 140 def parse_document_block_body children = [] loop do if peek?(LESS_THAN_SYMBOL) start = expect(LESS_THAN_SYMBOL) break if peek?(SLASH_SYMBOL) children << (start) else children << parse_document_text end end Node::Root.new(children: children) end |
#parse_document_command(start, name, arguments) ⇒ Node::Command
Parses a document command. This is essentially a message to the compiler about the document, to alter how the document is processed.
command ::= '<' TEXT *command-argument '/' '>'
57 58 59 60 61 62 63 |
# File 'lib/brandish/parser/main.rb', line 57 def parse_document_command(start, name, arguments) expect(SLASH_SYMBOL) stop = expect(GREATER_THAN_SYMBOL) Node::Command.new(name: name, arguments: arguments, location: start.location.union(stop.location)) end |
#parse_document_command_argument ⇒ Node::Pair
Parses a document command argument. This is an argument to a command. All arguments are key-value pairs.
command-argument ::= *space command-argument-key *space '=' *space command-argument-value *space
71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/brandish/parser/main.rb', line 71 def parse_document_command_argument parse_skip_space key = parse_document_command_argument_key parse_skip_space expect(EQUAL_SYMBOL) parse_skip_space value = parse_document_command_argument_value parse_skip_space Node::Pair.new(key: key, value: value) end |
#parse_document_command_argument_key ⇒ Scanner::Token
The key for the command argument.
command-argument-key ::= TEXT
88 89 90 |
# File 'lib/brandish/parser/main.rb', line 88 def parse_document_command_argument_key expect(TEXT_SYMBOL) end |
#parse_document_command_argument_value ⇒ Node
The value for the command argument. This can be either a string, or a Node::Text with a single token. If it's a string, it's parsed with #parse_document_string; otherwise, it grabs one token that's valid for a Node::Text node.
command-argument-value ::= string / TEXT
100 101 102 103 104 105 106 |
# File 'lib/brandish/parser/main.rb', line 100 def parse_document_command_argument_value if peek?(QUOTE_SYMBOL) parse_document_string else Node::Text.new(tokens: [expect(Node::Text::TOKENS)]) end end |
#parse_document_element ⇒ Node
Parses a single element in the docuemnt. If the next token is a less-than sign, it calls #parse_document_meta; otherwise, it calls #parse_document_text.
27 28 29 |
# File 'lib/brandish/parser/main.rb', line 27 def parse_document_element peek?(LESS_THAN_SYMBOL) ? : parse_document_text end |
#parse_document_meta(start = expect(LESS_THAN_SYMBOL)) ⇒ Node
parses a "meta" element from the document. In this sense, it is anything that doesn't correspond 1-to-1 to the destination document. If the next token after the less-than sign is an at-sign, it calls #parse_document_command; otherwise, it calls #parse_document_block.
37 38 39 40 41 42 43 44 45 46 |
# File 'lib/brandish/parser/main.rb', line 37 def (start = expect(LESS_THAN_SYMBOL)) name = expect(TEXT_SYMBOL) parse_skip_space arguments = collect(SLASH_OR_GREATER_THAN_SYMBOL) { parse_document_command_argument } if peek?(SLASH_SYMBOL) parse_document_command(start, name, arguments) else parse_document_block(start, name, arguments) end end |
#parse_document_string ⇒ Node::String
Parses a "string." This is a series of text encapulated by quotes. Strings can contain more characters than just regular text, but right now, strings are only used for command argument values.
string ::= '"' *(TEXT / SPACE / LINE / NUMERIC / ESCAPE / '<' / '>' / '=') '"'
162 163 164 165 166 167 168 169 |
# File 'lib/brandish/parser/main.rb', line 162 def parse_document_string start = expect(QUOTE_SYMBOL) children = collect(QUOTE_SYMBOL) { expect(Node::String::TOKENS) } stop = expect(QUOTE_SYMBOL) location = start.location.union(stop.location) Node::String.new(tokens: children, location: location) end |
#parse_document_text ⇒ Node::Text
Parses a document for text. This is just regular text tokens. For a list of tokens that are allowed, see Node::Text::TOKENS.
text ::= *(TEXT / SPACE / LINE / NUMERIC / ESCAPE / '/' / '"' / '=')
177 178 179 180 181 |
# File 'lib/brandish/parser/main.rb', line 177 def parse_document_text children = [expect(Node::Text::TOKENS)] children << expect(Node::Text::TOKENS) while peek?(Node::Text::TOKENS) Node::Text.new(tokens: children) end |
#parse_skip_space ⇒ void
This method returns an undefined value.
Skips over nodes as long as they're space nodes.
186 187 188 |
# File 'lib/brandish/parser/main.rb', line 186 def parse_skip_space expect(SPACE_SYMBOLS) while peek?(SPACE_SYMBOLS) end |