class KPeg::GrammarRenderer
Public Class Methods
escape(str, embed=false)
click to toggle source
# File lib/kpeg/grammar_renderer.rb, line 66 def self.escape(str, embed=false) parc = StringEscape.new(str) rule = (embed ? "embed" : nil) unless parc.parse(rule) parc.raise_error end return parc.text end
new(gram)
click to toggle source
# File lib/kpeg/grammar_renderer.rb, line 5 def initialize(gram) @grammar = gram end
Public Instance Methods
parens?(op)
click to toggle source
# File lib/kpeg/grammar_renderer.rb, line 57 def parens?(op) case op when Sequence, AndPredicate, NotPredicate return true end false end
render(io)
click to toggle source
# File lib/kpeg/grammar_renderer.rb, line 9 def render(io) widest = @grammar.rules.keys.sort { |a,b| a.size <=> b.size }.last indent = widest.size @grammar.variables.sort.each do |name, value| io.print "%% #{name} = #{value}\n" end unless @grammar.variables.empty? io.print "\n" end @grammar.directives.sort_by { |name,| name }.each do |name, act| io.print "%% #{name} {" io.print act.action io.print "}\n\n" end @grammar.setup_actions.each do |act| io.print "%% {" io.print act.action io.print "}\n\n" end @grammar.rule_order.each do |name| rule = @grammar.find(name) io.print(' ' * (indent - name.size)) io.print "#{name} = " op = rule.op if op.kind_of? Choice op.ops.each_with_index do |r,idx| unless idx == 0 io.print "\n#{' ' * (indent+1)}| " end render_op io, r end else render_op io, op end io.puts end end
render_op(io, op)
click to toggle source
# File lib/kpeg/grammar_renderer.rb, line 78 def render_op(io, op) case op when Dot io.print "." when LiteralString esc = GrammarRenderer.escape op.string io.print '"' io.print esc io.print '"' when LiteralRegexp io.print op.regexp.inspect when CharRange io.print "[#{op.start}-#{op.fin}]" when Sequence op.ops.each_with_index do |r,idx| unless idx == 0 io.print " " end render_op io, r end when Choice io.print "(" op.ops.each_with_index do |r,idx| unless idx == 0 io.print " | " end render_op io, r end io.print ")" when Multiple if parens?(op.op) io.print "(" render_op io, op.op io.print ")" else render_op io, op.op end if op.max if op.min == 0 and op.max == 1 io.print "?" else io.print "[#{op.min}, #{op.max}]" end elsif op.min == 0 io.print "*" elsif op.min == 1 io.print "+" else io.print "[#{op.min},*]" end when AndPredicate io.print "&" if parens?(op.op) io.print "(" render_op io, op.op io.print ")" else render_op io, op.op end when NotPredicate io.print "!" if parens?(op.op) io.print "(" render_op io, op.op io.print ")" else render_op io, op.op end when RuleReference if op.arguments io.print "#{op.rule_name}#{op.arguments}" else io.print "#{op.rule_name}" end when InvokeRule if op.arguments io.print "@#{op.rule_name}#{op.arguments}" else io.print "@#{op.rule_name}" end when ForeignInvokeRule if op.arguments io.print "%#{op.grammar_name}.#{op.rule_name}#{op.arguments}" else io.print "%#{op.grammar_name}.#{op.rule_name}" end when Tag if parens?(op.op) io.print "(" render_op io, op.op io.print ")" else render_op io, op.op end if op.tag_name io.print ":#{op.tag_name}" end when Action io.print "{#{op.action}}" when Collect io.print "< " render_op io, op.op io.print " >" when Bounds io.print "@< " render_op io, op.op io.print " >" else raise "Unknown op type - #{op.class}" end end