class SimpleTemplates::Parser
Parsing the SimpleTemplate means verifying that there are no malformed tags, and all tags are in the ‘allowed’ list.
Constants
- Error
A
Struct
that takes a message to create a parser error- FRIENDLY_TAG_NAMES
A
static
Hash with the meaning of each tag name @return [Hash{Symbol => String}]
Attributes
allowed_placeholders[R]
tokens[R]
unescapes[R]
Public Class Methods
new(unescapes, tokens, allowed_placeholders)
click to toggle source
Initializes a new Parser
. @param unescapes [SimpleTemplates::Unescapes] a Unescapes object @param tokens <Array> a list of tokens @param allowed_placeholders
<Array> a list with allowed
placeholders if is left as nil, then all placeholders are permitted
# File lib/simple_templates/parser.rb, line 26 def initialize(unescapes, tokens, allowed_placeholders) @unescapes = unescapes.clone.freeze @tokens = tokens.clone.freeze @allowed_placeholders = allowed_placeholders && allowed_placeholders.clone.freeze end
Public Instance Methods
parse()
click to toggle source
Returns a Parser::Result containing the parsed AST
nodes, the errors found when parsing and the remaining tokens that have not been parsed. @return [Array<Array<SimpleTemplates::AST::Node>,
Array<SimpleTemplates::Parser::Error>, Array<SimpleTemplates::Lexer::Token>>]
# File lib/simple_templates/parser.rb, line 39 def parse ast = [] errors = [] tok_stream = tokens.dup while tok_stream.any? parser = detect_parser(tok_stream) if parser.nil? errors << Error.new("Encountered unexpected token in stream " + "(#{FRIENDLY_TAG_NAMES[tok_stream.first.type]}), but expected to " + "see one of the following types: #{acceptable_starting_tokens}.") tok_stream = [] else template, errors_result, remaining_tokens = parser.parse if remaining_tokens.nil? raise "Parser #{parser.class} shouldn't return nil remaining " + "tokens (should be an Array), please report this bug." end if errors_result.empty? tok_stream = remaining_tokens ast = ast.concat(template) else # Once we get a syntax error, we can't really determine if anything # else is broken syntactically, so return with the first Error. tok_stream = [] errors.concat(errors_result) end end end errors.concat(invalid_node_content_errors(ast)) [ast, errors, tok_stream] end
Private Instance Methods
acceptable_starting_tokens()
click to toggle source
# File lib/simple_templates/parser.rb, line 93 def acceptable_starting_tokens (Placeholder::STARTING_TOKENS | Text::STARTING_TOKENS).map do |tag| FRIENDLY_TAG_NAMES[tag] end.join(', ') end
detect_parser(tokens_to_parse)
click to toggle source
# File lib/simple_templates/parser.rb, line 99 def detect_parser(tokens_to_parse) toks = tokens_to_parse.clone.freeze [Placeholder, Text].each do |parser_class| if parser_class.applicable?(toks) return parser_class.new(unescapes, toks, allowed_placeholders) end end nil end
invalid_node_content_errors(ast)
click to toggle source
# File lib/simple_templates/parser.rb, line 86 def invalid_node_content_errors(ast) ast.reject(&:allowed?).map do |node| Error.new("Invalid #{node.name} with contents, '#{node.contents}' " + "found starting at position #{node.pos}.") end end