Entry 4891

Gorgyrella

   

Submitted by anonymous on June 16, 2010 at 10:13 a.m.
Language: Ragel in Ruby Host. Code size: 4.0 KB.

module Gorgyrella
  class Parser
  %%{
    machine gorgyrella_parser;
    
    action raise_error {
       context = data[p - 30, 60].pack("c*") rescue
       context ||= data[p - 10, 20].pack("c*") rescue
       context ||= data[p-10, 10].pack("c*")
       context ||= "not available"
       raise "an error occurred parsing character " + p.to_s + " code: " + data[p].to_s + " chr: ->" + data[p, 1].pack("c*") + "<- \ncontext: " + context
    }
  
    action s {
      start = p
    }
  
    action l {
      text = data[start, p - start].pack("c*").strip
    }
  
    action reset_vars {
       filename = nil
       section = nil
       format = nil
       language = nil
       command = nil
    }
  
    action process_command {
       case command
       when :include
        builder.append_section(
            :command => 'include', 
            :file => filename, 
            :section => section, 
            :format => format, 
            :language => language
         )
       when :export
         builder.append_section(:section => section, :language => language)
       when :end
         builder.append_section
       else
        raise command
       end
    }
    
    action start_line {
       location = "start"
       line_start_pos = p
    }
    
    action finish_line {
       current_line_text = data[line_start_pos, p - line_start_pos].pack("c*")
       line_data << [p, cs, current_line_text]
    }
    
    action trace {
       $stdout.write "\nchar #{ sprintf("%03d", p)} #{data[p, 1].pack("c*")} state #{cs} #{location}"
    }
    
     ws = [ \t];
     eol = "\n" | "\r\n";
   
     identifier = (alpha (alpha | '.' | '_' | '-')*) >s %l;
     string = '"' . (any - '"' - eol)* >s %l . '"'; # token STRING: '\'([^\\n\'\\\\]|\\\\.)*\'|"([^\\n"\\\\]|\\\\.)*"'
     number = digit+ >s %l;
   
     filename = string %{filename = text } ;
     section = (identifier|string|number) %{section = text} ;
     format= identifier %{format = text} ;
     language = identifier %{language = text} ;
     
     section_format_language = (section) | (section ws+ format) | (section ws+ format ws+ language) ;
  
    include_section = 'include' ws+ filename ws+ section_format_language;
    export_section = 'export' ws+ section (ws+ language)?;
    end_section = 'end' ws*;
   
    command = 
       include_section >{location = 'include command'} >reset_vars %{ command = :include } | 
       export_section >{location = 'export command'} >reset_vars %{ command = :export } | 
       end_section >{location = 'end command'} %{ command = :end }
    ;
  
    starter = ("###"|'%%%'|'///') . " @";
    
    non_starter = [^#%/] - eol;
    false_start_hash = '#'{1,2} . ([^#] - eol) ;
    false_start_percent =  '%'{1,2} . ([^%] - eol) ;
    false_start_fwd =  '/'{1,2} . ([^/] - eol) ;
    followed_by_zlen = ('%'{1,3} | '#' {1,3} | '/' {1,3}) . eol;
    no_at = ("###"|'%%%'|'///') . ' ' . [^@];
    more_than_three = ("####"|'%%%%'|'////');
    
    not_starter =  non_starter | false_start_hash | false_start_percent | false_start_fwd | no_at  | followed_by_zlen | more_than_three;
  
    statement = (ws* . starter . command %process_command) ;
    junk = (ws* . not_starter . (any - eol)* )  ;
  
    line = (statement | junk | zlen) >start_line . eol %finish_line %{ builder.append_line(current_line_text.chomp) unless location =~ /command/ } ;
    document := line* $!raise_error;
  
  }%%
   
     %% write data;
     
     ### @export "run-machine"
     def self.run_machine(data, test_mode = false)
       # puts "Running the state machine with input #{data}..."
       data += "\n\n"
       data = data.unpack("c*") if data.is_a?(String)
       
       line_counter = 0
       line_data = []
     
       builder = Builder.new
     
       eof = -1
  
       %% write init;
       %% write exec;
       
   
       if test_mode
         [builder, line_data]
       else
         builder
      end
    end
    ### @end
  end
end

This snippet took 0.11 seconds to highlight.

Back to the Entry List or Home.

Delete this entry (admin only).