Class: Giter8::Parsers::TemplateParser

Inherits:
Object
  • Object
show all
Defined in:
lib/giter8/parsers/template_parser.rb

Overview

TemplateParser implements the main FSM to parse Giter8 templates

Constant Summary collapse

STATE_LITERAL =
1
STATE_TEMPLATE_NAME =
2
STATE_TEMPLATE_COMBINED_FORMATTER =
3
STATE_TEMPLATE_CONDITIONAL_EXPRESSION =
4
STATE_TEMPLATE_CONDITIONAL_EXPRESSION_END =
5
STATE_TEMPLATE_CONDITIONAL_THEN =
6
STATE_TEMPLATE_CONDITIONAL_ELSE_IF =
7
STATE_TEMPLATE_CONDITIONAL_ELSE =
8
STATE_TEMPLATE_OPTION_NAME =
9
STATE_TEMPLATE_OPTION_VALUE_BEGIN =
10
STATE_TEMPLATE_OPTION_VALUE =
11
STATE_TEMPLATE_OPTION_OR_END =
12
STATE_THEN_OR_ELSE_IF =
[STATE_TEMPLATE_CONDITIONAL_THEN, STATE_TEMPLATE_CONDITIONAL_ELSE_IF].freeze
STATE_NAMES =
{
  STATE_LITERAL => "STATE_LITERAL",
  STATE_TEMPLATE_NAME => "STATE_TEMPLATE_NAME",
  STATE_TEMPLATE_COMBINED_FORMATTER => "STATE_TEMPLATE_COMBINED_FORMATTER",
  STATE_TEMPLATE_CONDITIONAL_EXPRESSION => "STATE_TEMPLATE_CONDITIONAL_EXPRESSION",
  STATE_TEMPLATE_CONDITIONAL_EXPRESSION_END => "STATE_TEMPLATE_CONDITIONAL_EXPRESSION_END",
  STATE_TEMPLATE_CONDITIONAL_THEN => "STATE_TEMPLATE_CONDITIONAL_THEN",
  STATE_TEMPLATE_CONDITIONAL_ELSE_IF => "STATE_TEMPLATE_CONDITIONAL_ELSE_IF",
  STATE_TEMPLATE_CONDITIONAL_ELSE => "STATE_TEMPLATE_CONDITIONAL_ELSE",
  STATE_TEMPLATE_OPTION_NAME => "STATE_TEMPLATE_OPTION_NAME",
  STATE_TEMPLATE_OPTION_VALUE_BEGIN => "STATE_TEMPLATE_OPTION_VALUE_BEGIN",
  STATE_TEMPLATE_OPTION_VALUE => "STATE_TEMPLATE_OPTION_VALUE",
  STATE_TEMPLATE_OPTION_OR_END => "STATE_TEMPLATE_OPTION_OR_END"
}.freeze
ESCAPE =
"\\"
DELIM =
"$"
NEWLINE =
"\n"
SEMICOLON =
";"
EQUALS =
"="
QUOT =
'"'
COMMA =
","
SPACE =
" "
HTAB =
"\t"
LPAREN =
"("
RPAREN =
")"
DOT =
"."
UNDESCORE =
"_"
DASH =
"-"
TRUTHY =
"truthy"
PRESENT =
"present"
VALID_LETTERS =
(("a".."z").to_a + ("A".."Z").to_a).freeze
VALID_DIGITS =
("0".."9").to_a.freeze
VALID_COMPARATORS =
[TRUTHY, PRESENT].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ TemplateParser

Initialises a new TemplateParser instance. See also: TemplateParser.parse



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/giter8/parsers/template_parser.rb', line 68

def initialize(opts = {})
  @ast = AST.new
  @tmp = []
  @template_name = []
  @option_name = []
  @option_value = []
  @template_options = {}
  @state_stack = []
  @state = STATE_LITERAL
  @last_chr = ""
  @debug = false
  @source = opts[:source] || "unknown"
  @line = 1
  @column = 0
  @anchors = {
    template_name: [0, 0],
    conditional: [0, 0]
  }
end

Class Method Details

.parse(template, opts = {}) ⇒ Object

Parses a given template string with provided options. Options is a hash that currently only supports the :source key, which must be the name of the file being parsed. This key is used to identify any errors whilst parsing the contents and will be provided on any raised errors. Returns an AST instance of the provided template string.



62
63
64
# File 'lib/giter8/parsers/template_parser.rb', line 62

def self.parse(template, opts = {})
  new(opts).parse(template)
end

Instance Method Details

#debug!Object

Enables debugging logs for this instance. Contents will be written to the standard output.



90
91
92
# File 'lib/giter8/parsers/template_parser.rb', line 90

def debug!
  @debug = true
end

#parse(data) ⇒ Object

Returns an AST object of a provided string. This consumes each character within the provided data.



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/giter8/parsers/template_parser.rb', line 96

def parse(data)
  debug("begin parsing source `#{@source}'")
  data.chars.each do |chr|
    chr = chr.chr

    pchr = chr
    pchr = '\n' if pchr == NEWLINE
    debug("CHR: #{pchr}, STATE: #{state_name(@state)}")

    consume(chr)

    @column += 1
    if chr == NEWLINE
      @column = 0
      @line += 1
    end
    @last_chr = chr
  end

  unexpected_eof if @state != STATE_LITERAL

  commit_literal

  debug("finished parsing `#{@source}'")
  @ast.clean
end