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
15 def fullscan_epp
16   result = []
17   scan_epp {|token, value| result.push([token, value]) }
18   result
19 end
interpolate_epp(skip_leading=false) click to toggle source
    # File lib/puppet/pops/parser/epp_support.rb
 60 def interpolate_epp(skip_leading=false)
 61   scn = @scanner
 62   ctx = @lexing_context
 63   eppscanner = EppScanner.new(scn)
 64   before = scn.pos
 65 
 66   s = eppscanner.scan(skip_leading)
 67 
 68   case eppscanner.mode
 69   when :text
 70     # Should be at end of scan, or something is terribly wrong
 71     unless @scanner.eos?
 72       lex_error(Issues::EPP_INTERNAL_ERROR, :error => 'template scanner returns text mode and is not and end of input')
 73     end
 74     if s
 75       # s may be nil if scanned text ends with an epp tag (i.e. no trailing text).
 76       enqueue_completed([:RENDER_STRING, s, scn.pos - before], before)
 77     end
 78     ctx[:epp_open_position] = nil
 79     # do nothing else, scanner is at the end
 80 
 81   when :error
 82     lex_error(eppscanner.issue)
 83 
 84   when :epp
 85     # It is meaningless to render empty string segments, and it is harmful to do this at
 86     # the start of the scan as it prevents specification of parameters with <%- ($x, $y) -%>
 87     #
 88     if s && s.length > 0
 89       enqueue_completed([:RENDER_STRING, s, scn.pos - before], before)
 90     end
 91     # switch epp_mode to general (embedded) pp logic (non rendered result)
 92     ctx[:epp_mode] = :epp
 93     ctx[:epp_open_position] = scn.pos
 94 
 95   when :expr
 96     # It is meaningless to render an empty string segment
 97     if s && s.length > 0
 98       enqueue_completed([:RENDER_STRING, s, scn.pos - before], before)
 99     end
100     enqueue_completed(TOKEN_RENDER_EXPR, before)
101     # switch mode to "epp expr interpolation"
102     ctx[:epp_mode] = :expr
103     ctx[:epp_open_position] = scn.pos
104   else
105     lex_error(Issues::EPP_INTERNAL_ERROR, :error => "Unknown mode #{eppscanner.mode} returned by template scanner")
106   end
107   nil
108 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
29 def scan_epp
30   # PERFORMANCE note: it is faster to access local variables than instance variables.
31   # This makes a small but notable difference since instance member access is avoided for
32   # every token in the lexed content.
33   #
34   scn   = @scanner
35   ctx   = @lexing_context
36   queue = @token_queue
37 
38   lex_error(Issues::EPP_INTERNAL_ERROR, :error => 'No string or file given to lexer to process.') unless scn
39 
40   ctx[:epp_mode] = :text
41   enqueue_completed([:EPP_START, nil, 0], 0)
42 
43   interpolate_epp
44 
45   # This is the lexer's main loop
46   until queue.empty? && scn.eos? do
47     token = queue.shift || lex_token
48     if token
49       yield [ ctx[:after] = token[0], token[1] ]
50     end
51   end
52   if ctx[:epp_open_position]
53     lex_error(Issues::EPP_UNBALANCED_TAG, {}, ctx[:epp_position])
54   end
55 
56   # Signals end of input
57   yield [false, false]
58 end