module Puppet::Pops::Parser::EppSupport

Constants

TOKEN_RENDER_EXPR
TOKEN_RENDER_STRING

Public Instance Methods

fullscan_epp() click to toggle source

Scans all of the content and returns it in an array Note that the terminating [false, false] token is included in the result.

   # File lib/puppet/pops/parser/epp_support.rb
16 def fullscan_epp
17   result = []
18   scan_epp {|token, value| result.push([token, value]) }
19   result
20 end
interpolate_epp(skip_leading=false) click to toggle source
    # File lib/puppet/pops/parser/epp_support.rb
 61 def interpolate_epp(skip_leading=false)
 62   scn = @scanner
 63   ctx = @lexing_context
 64   eppscanner = EppScanner.new(scn)
 65   before = scn.pos
 66 
 67   s = eppscanner.scan(skip_leading)
 68 
 69   case eppscanner.mode
 70   when :text
 71     # Should be at end of scan, or something is terribly wrong
 72     unless @scanner.eos?
 73       lex_error(Issues::EPP_INTERNAL_ERROR, :error => 'template scanner returns text mode and is not and end of input')
 74     end
 75     if s
 76       # s may be nil if scanned text ends with an epp tag (i.e. no trailing text).
 77       enqueue_completed([:RENDER_STRING, s, scn.pos - before], before)
 78     end
 79     ctx[:epp_open_position] = nil
 80     # do nothing else, scanner is at the end
 81 
 82   when :error
 83     lex_error(eppscanner.issue)
 84 
 85   when :epp
 86     # It is meaningless to render empty string segments, and it is harmful to do this at
 87     # the start of the scan as it prevents specification of parameters with <%- ($x, $y) -%>
 88     #
 89     if s && s.length > 0
 90       enqueue_completed([:RENDER_STRING, s, scn.pos - before], before)
 91     end
 92     # switch epp_mode to general (embedded) pp logic (non rendered result)
 93     ctx[:epp_mode] = :epp
 94     ctx[:epp_open_position] = scn.pos
 95 
 96   when :expr
 97     # It is meaningless to render an empty string segment
 98     if s && s.length > 0
 99       enqueue_completed([:RENDER_STRING, s, scn.pos - before], before)
100     end
101     enqueue_completed(TOKEN_RENDER_EXPR, before)
102     # switch mode to "epp expr interpolation"
103     ctx[:epp_mode] = :expr
104     ctx[:epp_open_position] = scn.pos
105   else
106     lex_error(Issues::EPP_INTERNAL_ERROR, :error => "Unknown mode #{eppscanner.mode} returned by template scanner")
107   end
108   nil
109 end
scan_epp() { |ctx = token, token| ... } click to toggle source

A block must be passed to scan. It will be called with two arguments, a symbol for the token, and an instance of LexerSupport::TokenValue PERFORMANCE NOTE: The TokenValue is designed to reduce the amount of garbage / temporary data and to only convert the lexer's internal tokens on demand. It is slightly more costly to create an instance of a class defined in Ruby than an Array or Hash, but the gain is much bigger since transformation logic is avoided for many of its members (most are never used (e.g. line/pos information which is only of value in general for error messages, and for some expressions (which the lexer does not know about).

   # File lib/puppet/pops/parser/epp_support.rb
30 def scan_epp
31   # PERFORMANCE note: it is faster to access local variables than instance variables.
32   # This makes a small but notable difference since instance member access is avoided for
33   # every token in the lexed content.
34   #
35   scn   = @scanner
36   ctx   = @lexing_context
37   queue = @token_queue
38 
39   lex_error(Issues::EPP_INTERNAL_ERROR, :error => 'No string or file given to lexer to process.') unless scn
40 
41   ctx[:epp_mode] = :text
42   enqueue_completed([:EPP_START, nil, 0], 0)
43 
44   interpolate_epp
45 
46   # This is the lexer's main loop
47   until queue.empty? && scn.eos? do
48     token = queue.shift || lex_token
49     if token
50       yield [ ctx[:after] = token[0], token[1] ]
51     end
52   end
53   if ctx[:epp_open_position]
54     lex_error(Issues::EPP_UNBALANCED_TAG, {}, ctx[:epp_position])
55   end
56 
57   # Signals end of input
58   yield [false, false]
59 end