Class: Luoma::Parser
- Inherits:
-
Object
- Object
- Luoma::Parser
- Defined in:
- lib/luoma/parser.rb,
sig/luoma/parser.rbs
Direct Known Subclasses
Constant Summary collapse
- TERMINATE_EXPRESSION =
Set.new(%i[ token_wc token_out_end token_tag_end token_text token_rparen token_eoi token_if token_else token_interpolation_end ]).freeze
Instance Attribute Summary collapse
-
#env ⇒ Environment
readonly
Returns the value of attribute env.
-
#source ⇒ String
readonly
Returns the value of attribute source.
-
#template_name ⇒ String
readonly
Returns the value of attribute template_name.
Class Method Summary collapse
-
.parse(env, source, template_name, tokens) ⇒ t_block
(Environment, String, String, Array) -> t_block.
Instance Method Summary collapse
-
#carry_whitespace_control ⇒ void
() -> void.
-
#current ⇒ t_token
() -> t_token.
-
#current_value ⇒ String
() -> String.
-
#eat(kind, message: nil) ⇒ t_token
(t_token_kind, ?message: String?) -> t_token.
-
#eat_empty_tag(name) ⇒ t_token
(String) -> t_token.
-
#eat_one_of(kinds) ⇒ t_token
(Set) -> t_token.
-
#eat_tag(name) ⇒ t_token
(String) -> t_token.
-
#expect_expression ⇒ void
Raise an error if we're not at the start of an expression.
-
#initialize(env, source, template_name, tokens) ⇒ Parser
constructor
(Environment, String, String, Array) -> void.
-
#kind ⇒ t_token_kind
() -> t_token_kind.
-
#next ⇒ t_token
() -> t_token.
-
#parse_arguments(require_commas: nil) ⇒ Array[Expression | KeywordArgument]
(?require_commas: bool?) -> Array[Expression | KeywordArgument].
-
#parse_block(stop: nil) ⇒ t_block
(?stop: Set?) -> t_block.
-
#parse_expression(precedence: 1) ⇒ Expression
(?precedence: Integer) -> Expression.
-
#parse_ident ⇒ Name
() -> Name.
-
#parse_keyword_arguments(require_commas: nil) ⇒ Array[KeywordArgument]
(?require_commas: bool?) -> Array.
-
#parse_name ⇒ Name
Parse an identifier, possibly surrounded by quotes.
-
#parse_positional_arguments(require_commas: nil) ⇒ Array[Expression]
(?require_commas: bool?) -> Array.
-
#parse_string_literal ⇒ StringLiteral
() -> StringLiteral.
- #peek(offset = 1) ⇒ t_token
-
#peek_tag_name ⇒ String
() -> String.
-
#peek_whitespace_control ⇒ String?
() -> String?.
-
#skip_whitespace_control ⇒ void
() -> void.
-
#tag?(name) ⇒ Boolean
Return
trueif we're at the start of a tag namedname. -
#tags(names) ⇒ String?
(Set) -> String?.
Constructor Details
#initialize(env, source, template_name, tokens) ⇒ Parser
(Environment, String, String, Array) -> void
25 26 27 28 29 30 31 32 33 34 |
# File 'lib/luoma/parser.rb', line 25 def initialize(env, source, template_name, tokens) @env = env @source = source @template_name = template_name @tokens = tokens @pos = 0 @eoi = [:token_eoi, source.length, source.length] @whitespace_control_carry = nil #: "-" | "+" | "~" | nil end |
Instance Attribute Details
#env ⇒ Environment (readonly)
Returns the value of attribute env.
5 6 7 |
# File 'lib/luoma/parser.rb', line 5 def env @env end |
#source ⇒ String (readonly)
Returns the value of attribute source.
5 6 7 |
# File 'lib/luoma/parser.rb', line 5 def source @source end |
#template_name ⇒ String (readonly)
Returns the value of attribute template_name.
5 6 7 |
# File 'lib/luoma/parser.rb', line 5 def template_name @template_name end |
Class Method Details
.parse(env, source, template_name, tokens) ⇒ t_block
(Environment, String, String, Array) -> t_block
20 21 22 |
# File 'lib/luoma/parser.rb', line 20 def self.parse(env, source, template_name, tokens) new(env, source, template_name, tokens).parse_block end |
Instance Method Details
#carry_whitespace_control ⇒ void
This method returns an undefined value.
() -> void
37 38 39 |
# File 'lib/luoma/parser.rb', line 37 def carry_whitespace_control @whitespace_control_carry = (Luoma.get_token_value(self.next, @source) if kind == :token_wc) end |
#current ⇒ t_token
() -> t_token
42 43 44 |
# File 'lib/luoma/parser.rb', line 42 def current @tokens[@pos] || @eoi end |
#current_value ⇒ String
() -> String
52 53 54 |
# File 'lib/luoma/parser.rb', line 52 def current_value Luoma.get_token_value(@tokens[@pos] || @eoi, @source) end |
#eat(kind, message: nil) ⇒ t_token
(t_token_kind, ?message: String?) -> t_token
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/luoma/parser.rb', line 68 def eat(kind, message: nil) token = @tokens[@pos] || @eoi unless token.first == kind kind_ = Luoma::TOKEN_KIND_MAP[token.first] value = Luoma.get_token_value(token, @source).inspect raise TemplateSyntaxError.new( || "unexpected #{kind_} (#{value})", token, @source, @template_name ) end @pos += 1 token end |
#eat_empty_tag(name) ⇒ t_token
(String) -> t_token
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/luoma/parser.rb', line 86 def eat_empty_tag(name) eat(:token_tag_start, message: "expected tag #{name}") @pos += 1 if kind == :token_wc # steep:ignore token = eat(:token_tag_name, message: "expected tag #{name}") got = Luoma.get_token_value(token, @source) unless got == name raise TemplateSyntaxError.new( "unexpected tag #{got.inspect}", token, @source, @template_name ) end carry_whitespace_control eat(:token_tag_end, message: "expected a closing tag delimiter") token end |
#eat_one_of(kinds) ⇒ t_token
(Set) -> t_token
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/luoma/parser.rb', line 107 def eat_one_of(kinds) token = @tokens[@pos] || @eoi unless kinds.include?(token.first) kind_ = Luoma::TOKEN_KIND_MAP[token.first] value = Luoma.get_token_value(token, @source).inspect raise TemplateSyntaxError.new( "unexpected #{kind_} (#{value})", token, @source, @template_name ) end @pos += 1 token end |
#eat_tag(name) ⇒ t_token
(String) -> t_token
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/luoma/parser.rb', line 125 def eat_tag(name) eat(:token_tag_start, message: "expected tag #{name}") @pos += 1 if kind == :token_wc # steep:ignore token = eat(:token_tag_name, message: "expected tag #{name}") got = Luoma.get_token_value(token, @source) unless got == name raise TemplateSyntaxError.new( "unexpected tag #{got.inspect}", token, @source, @template_name ) end # Ignore everything between the tag name and the closing tag delimiter. @pos += 1 until TERMINATE_EXPRESSION.include?(kind) carry_whitespace_control eat(:token_tag_end, message: "expected a closing tag delimiter") token end |
#expect_expression ⇒ void
This method returns an undefined value.
Raise an error if we're not at the start of an expression. () -> void
150 151 152 153 154 155 156 157 158 159 |
# File 'lib/luoma/parser.rb', line 150 def expect_expression if TERMINATE_EXPRESSION.include?(kind) raise TemplateSyntaxError.new( "missing expression", current, @source, @template_name ) end end |
#kind ⇒ t_token_kind
() -> t_token_kind
47 48 49 |
# File 'lib/luoma/parser.rb', line 47 def kind (@tokens[@pos] || @eoi).first #: t_token_kind end |
#next ⇒ t_token
() -> t_token
57 58 59 60 61 |
# File 'lib/luoma/parser.rb', line 57 def next token = @tokens[@pos] || @eoi @pos += 1 token end |
#parse_arguments(require_commas: nil) ⇒ Array[Expression | KeywordArgument]
(?require_commas: bool?) -> Array[Expression | KeywordArgument]
162 163 164 |
# File 'lib/luoma/parser.rb', line 162 def parse_arguments(require_commas: nil) raise "not implemented" end |
#parse_block(stop: nil) ⇒ t_block
(?stop: Set?) -> t_block
167 168 169 |
# File 'lib/luoma/parser.rb', line 167 def parse_block(stop: nil) raise "not implemented" end |
#parse_expression(precedence: 1) ⇒ Expression
(?precedence: Integer) -> Expression
172 173 174 |
# File 'lib/luoma/parser.rb', line 172 def parse_expression(precedence: 1) raise "not implemented" end |
#parse_ident ⇒ Name
() -> Name
177 178 179 |
# File 'lib/luoma/parser.rb', line 177 def parse_ident raise "not implemented" end |
#parse_keyword_arguments(require_commas: nil) ⇒ Array[KeywordArgument]
(?require_commas: bool?) -> Array
182 183 184 |
# File 'lib/luoma/parser.rb', line 182 def parse_keyword_arguments(require_commas: nil) raise "not implemented" end |
#parse_name ⇒ Name
Parse an identifier, possibly surrounded by quotes. () -> Name
188 189 190 |
# File 'lib/luoma/parser.rb', line 188 def parse_name raise "not implemented" end |
#parse_positional_arguments(require_commas: nil) ⇒ Array[Expression]
(?require_commas: bool?) -> Array
193 194 195 |
# File 'lib/luoma/parser.rb', line 193 def parse_positional_arguments(require_commas: nil) raise "not implemented" end |
#parse_string_literal ⇒ StringLiteral
() -> StringLiteral
198 199 200 |
# File 'lib/luoma/parser.rb', line 198 def parse_string_literal raise "not implemented" end |
#peek(offset = 1) ⇒ t_token
63 64 65 |
# File 'lib/luoma/parser.rb', line 63 def peek(offset = 1) @tokens[@pos + offset] || @eoi end |
#peek_tag_name ⇒ String
() -> String
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/luoma/parser.rb', line 203 def peek_tag_name token = current token = peek if token.first == :token_wc unless token.first == :token_tag_name raise TemplateSyntaxError.new( "missing tag name", token, @source, @template_name ) end Luoma.get_token_value(token, @source) end |
#peek_whitespace_control ⇒ String?
() -> String?
220 221 222 223 |
# File 'lib/luoma/parser.rb', line 220 def peek_whitespace_control token = peek Luoma.get_token_value(token, @source) if token.first == :token_wc end |
#skip_whitespace_control ⇒ void
This method returns an undefined value.
() -> void
226 227 228 |
# File 'lib/luoma/parser.rb', line 226 def skip_whitespace_control @pos += 1 if kind == :token_wc end |
#tag?(name) ⇒ Boolean
Return true if we're at the start of a tag named name.
(String) -> bool
232 233 234 235 236 237 |
# File 'lib/luoma/parser.rb', line 232 def tag?(name) token = peek token = peek(2) if token.first == :token_wc token.first == :token_tag_name && Luoma.get_token_value(token, @source) == name end |
#tags(names) ⇒ String?
(Set) -> String?
242 243 244 245 246 247 248 249 250 |
# File 'lib/luoma/parser.rb', line 242 def (names) token = peek token = peek(2) if token.first == :token_wc return unless token.first == :token_tag_name name = Luoma.get_token_value(token, @source) name if names.include?(name) end |