Object
# File lib/rexical/generator.rb, line 47 47: def add_header( st ) 48: @scanner_header += "#{st}\n" 49: end
# File lib/rexical/generator.rb, line 57 57: def add_inner( st ) 58: @scanner_inner += "#{st}\n" 59: end
# File lib/rexical/generator.rb, line 77 77: def add_macro( st ) 78: ss = StringScanner.new(st) 79: ss.scan(/\s+/) 80: key = ss.scan(/\S+/) 81: ss.scan(/\s+/) 82: st = ss.post_match 83: len = st.size 84: ndx = 0 85: while ndx <= len 86: c = st[ndx,1] 87: ndx += 1 88: case c 89: when '\' 90: ndx += 1 91: next 92: when '#', ' ' 93: ndx -= 1 94: break 95: end 96: end 97: expr = st[0,ndx] 98: expr.gsub!('\ ', ' ') 99: key = '{' + key + '}' 100: @macro.each_pair do |k, e| 101: expr.gsub!(k) { |m| e } 102: end 103: @macro[key] = expr 104: rescue 105: raise ParseError, "parse error in add_macro:'#{st}'" 106: end
# File lib/rexical/generator.rb, line 62 62: def add_option( st ) 63: opts = st.split 64: opts.each do |opt| 65: case opt 66: when /ignorecase/ 67: @opt['--ignorecase'] = true 68: when /stub/ 69: @opt['--stub'] = true 70: when /independent/ 71: @opt['--independent'] = true 72: end 73: end 74: end
# File lib/rexical/generator.rb, line 109 109: def add_rule( rule_state, rule_expr, rule_action=nil ) 110: st = rule_expr.dup 111: @macro.each_pair do |k, e| 112: rule_expr.gsub!(k) { |m| e } 113: end 114: if rule_state.to_s[1,1] =~ /[A-Z]/ 115: @exclusive_states << rule_state unless @exclusive_states.include?(rule_state) 116: exclusive_state = rule_state 117: start_state = nil 118: else 119: exclusive_state = nil 120: start_state = rule_state 121: end 122: rule = [exclusive_state, start_state, rule_expr, rule_action] 123: @rules << rule 124: rescue 125: raise ParseError, "parse error in add_rule:'#{st}'" 126: end
# File lib/rexical/generator.rb, line 132 132: def next_line 133: @lineno += 1 134: @grammar_lines.scan_until(/\n/).chomp 135: rescue 136: nil 137: end
# File lib/rexical/generator.rb, line 139 139: def parse 140: state1 = :HEAD 141: state2 = nil 142: state3 = nil 143: lastmodes = [] 144: while st = next_line 145: case state1 146: when :FOOT 147: add_footer st 148: 149: when :HEAD 150: ss = StringScanner.new(st) 151: if ss.scan(/class/) 152: state1 = :CLASS 153: st = ss.post_match.strip 154: if st =~ /^(\S+)::(\S+)/ 155: @module_name = $1 156: @class_name = $2 157: else 158: @module_name = nil 159: @class_name = st 160: end 161: else 162: add_header st 163: end 164: 165: when :CLASS 166: s = st.strip 167: next if s.size == 0 or s[0,1] == '#' 168: 169: ss = StringScanner.new(st) 170: if ss.scan(/option.*$/) 171: state2 = :OPTION 172: next 173: end 174: if ss.scan(/inner.*$/) 175: state2 = :INNER 176: next 177: end 178: if ss.scan(/macro.*$/) 179: state2 = :MACRO 180: next 181: end 182: if ss.scan(/rule.*$/) 183: state2 = :RULE 184: next 185: end 186: if ss.scan(/end.*$/) 187: state1 = :FOOT 188: next 189: end 190: 191: case state2 192: when :OPTION 193: add_option st 194: 195: when :INNER 196: add_inner st 197: 198: when :MACRO 199: add_macro st 200: 201: when :RULE 202: case state3 203: when nil 204: rule_state, rule_expr, rule_action = parse_rule(st) 205: if rule_action =~ /\s*\{/ 206: lastmodes = parse_action(rule_action, lastmodes) 207: if lastmodes.empty? 208: add_rule rule_state, rule_expr, rule_action 209: else 210: state3 = :CONT 211: rule_action += "\n" 212: end 213: else 214: add_rule rule_state, rule_expr 215: end 216: 217: when :CONT 218: rule_action += "#{st}\n" 219: lastmodes = parse_action(st, lastmodes) 220: if lastmodes.empty? 221: state3 = nil 222: add_rule rule_state, rule_expr, rule_action 223: else 224: end 225: 226: end # case state3 227: 228: end # case state2 229: 230: end # case state1 231: 232: end # while 233: 234: end
# File lib/rexical/generator.rb, line 250 250: def parse_action(st, lastmodes=[]) 251: modes = lastmodes 252: mode = lastmodes[1] 253: ss = StringScanner.new(st) 254: until ss.eos? 255: c = ss.scan(/./) 256: case c 257: when '#' 258: if (mode == :brace) or (mode == nil) 259: #p [c, mode, modes] 260: return modes 261: end 262: when '{' 263: if (mode == :brace) or (mode == nil) 264: mode = :brace 265: modes.push mode 266: end 267: when '}' 268: if (mode == :brace) 269: modes.pop 270: mode = modes[0] 271: end 272: when "'" 273: if (mode == :brace) 274: mode = :quote 275: modes.push mode 276: elsif (mode == :quote) 277: modes.pop 278: mode = modes[0] 279: end 280: when '"' 281: if (mode == :brace) 282: mode = :doublequote 283: modes.push mode 284: elsif (mode == :doublequote) 285: modes.pop 286: mode = modes[0] 287: end 288: when '`' 289: if (mode == :brace) 290: mode = :backquote 291: modes.push mode 292: elsif (mode == :backquote) 293: modes.pop 294: mode = modes[0] 295: end 296: end 297: end 298: #p [c, mode, modes] 299: return modes 300: end
# File lib/rexical/generator.rb, line 237 237: def parse_rule(st) 238: st.strip! 239: return if st.size == 0 or st[0,1] == '#' 240: ss = StringScanner.new(st) 241: ss.scan(/\s+/) 242: rule_state = ss.scan(/\:\S+/) 243: ss.scan(/\s+/) 244: rule_expr = ss.scan(/\S+/) 245: ss.scan(/\s+/) 246: [rule_state, rule_expr, ss.post_match] 247: end
# File lib/rexical/generator.rb, line 128 128: def read_grammar 129: @grammar_lines = StringScanner.new File.read(grammar_file) 130: end
# File lib/rexical/generator.rb, line 379 379: def write_scanner f = scanner_io 380: ## scan flag 381: flag = "" 382: flag += "i" if @opt['--ignorecase'] 383: ## header 384: f.printf REX_HEADER, Rexical::VERSION, grammar_file 385: 386: unless @opt['--independent'] 387: f.printf "require 'racc/parser'\n" 388: end 389: 390: @scanner_header.each_line do |s| 391: f.print s 392: end 393: if @module_name 394: f.puts "module #{@module_name}" 395: end 396: if @opt['--independent'] 397: f.puts "class #{@class_name}" 398: else 399: f.puts "class #{@class_name} < Racc::Parser" 400: end 401: 402: ## utility method 403: f.print REX_UTIL 404: 405: ## scanner method 406: 407: f.print def next_token return if @ss.eos? text = @ss.peek(1) @lineno += 1 if text == "\\n" token = case @state 408: 409: exclusive_states.each do |es| 410: f.printf when #{es ? es.to_s : "nil"} case 411: rules.each do |rule| 412: exclusive_state, start_state, rule_expr, rule_action = *rule 413: if es == exclusive_state 414: 415: if rule_action 416: if start_state 417: f.print when (state == #{start_state}) and (text = @ss.scan(/#{rule_expr}/#{flag})) action #{rule_action} 418: else 419: f.print when (text = @ss.scan(/#{rule_expr}/#{flag})) action #{rule_action} 420: end 421: else 422: if start_state 423: f.print when (state == #{start_state}) and (text = @ss.scan(/#{rule_expr}/#{flag})) ; 424: else 425: f.print when (text = @ss.scan(/#{rule_expr}/#{flag})) ; 426: end 427: end 428: 429: end 430: end 431: f.print else text = @ss.string[@ss.pos .. -1] raise ScanError, "can not match: '" + text + "'" end # if 432: end 433: f.print else raise ScanError, "undefined state: '" + state.to_s + "'" end # case state 434: if @opt['--debug'] 435: f.print p token 436: end 437: f.print token end # def next_token 438: 439: ## inner method 440: @scanner_inner.each_line do |s| 441: f.print s 442: end 443: f.puts "end # class" 444: f.puts "end # module" if @module_name 445: 446: ## footer 447: @scanner_footer.each_line do |s| 448: f.print s 449: end # case 450: 451: ## stub main 452: f.printf REX_STUB, @class_name, '"%s:%d:%s\n"' if @opt['--stub'] 453: f.close 454: 455: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.