Module: Racc
- Defined in:
- lib/racc/info.rb,
lib/racc/iset.rb,
lib/racc/state.rb,
lib/racc/parser.rb,
lib/racc/parser.rb,
lib/racc/grammar.rb,
lib/racc/exception.rb,
lib/racc/debugflags.rb,
lib/racc/sourcetext.rb,
lib/racc/parser-text.rb,
lib/racc/logfilegenerator.rb,
lib/racc/grammarfileparser.rb,
lib/racc/parserfilegenerator.rb,
lib/racc/statetransitiontable.rb,
ext/racc/cparse/cparse.c
Overview
--
Copyright (c) 1999-2006 Minero Aoki
This program is free software. You can distribute/modify this program under the same terms of ruby. see the file "COPYING".
++
Defined Under Namespace
Classes: Accept, ActionTable, CompileError, CparseParams, DebugFlags, Error, Goto, Grammar, GrammarFileParser, GrammarFileScanner, GroupEndMark, GroupStartMark, ISet, Item, LocationPointer, LogFileGenerator, Many1Mark, ManyMark, OptionMark, OrMark, ParseError, Parser, ParserClassGenerator, ParserFileGenerator, Prec, RRconflict, Reduce, Rule, SRconflict, Shift, SourceText, State, StateTransitionTable, StateTransitionTableGenerator, States, Sym, SymbolTable, UserAction
Constant Summary collapse
- VERSION =
'1.8.1'- Version =
VERSION- Copyright =
'Copyright (c) 1999-2006 Minero Aoki'- Racc_No_Extensions =
:nodoc:
false- PARSER_TEXT =
"#--\n# Copyright (c) 1999-2006 Minero Aoki\n#\n# This program is free software.\n# You can distribute/modify this program under the same terms of ruby.\n#\n# As a special exception, when this code is copied by Racc\n# into a Racc output file, you may use that output file\n# without restriction.\n#++\n\nunless $\".find {|p| p.end_with?('/racc/info.rb')}\n$\".push \"\#{__dir__}/racc/info.rb\"\n\nmodule Racc\n VERSION = '1.8.1'\n Version = VERSION\n Copyright = 'Copyright (c) 1999-2006 Minero Aoki'\nend\n\nend\n\n\nmodule Racc\n class ParseError < StandardError; end\nend\nunless defined?(::ParseError)\n ParseError = Racc::ParseError # :nodoc:\nend\n\n#--\nmodule Racc\n\n unless defined?(Racc_No_Extensions)\n Racc_No_Extensions = false # :nodoc:\n end\n\n class Parser\n\n Racc_Runtime_Version = ::Racc::VERSION\n Racc_Runtime_Core_Version_R = ::Racc::VERSION\n\n begin\n if Object.const_defined?(:RUBY_ENGINE) and RUBY_ENGINE == 'jruby'\n require 'jruby'\n require 'racc/cparse-jruby.jar'\n com.headius.racc.Cparse.new.load(JRuby.runtime, false)\n else\n begin\n ruby_version = /(\\d+\\.\\d+)/.match(::RUBY_VERSION)\n require \"racc/\#{ruby_version}/cparse\"\n rescue LoadError\n require 'racc/cparse'\n end\n end\n\n unless new.respond_to?(:_racc_do_parse_c, true)\n raise LoadError, 'old cparse.so'\n end\n if Racc_No_Extensions\n raise LoadError, 'selecting ruby version of racc runtime core'\n end\n\n Racc_Main_Parsing_Routine = :_racc_do_parse_c # :nodoc:\n Racc_YY_Parse_Method = :_racc_yyparse_c # :nodoc:\n Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_C # :nodoc:\n Racc_Runtime_Type = 'c' # :nodoc:\n rescue LoadError\n Racc_Main_Parsing_Routine = :_racc_do_parse_rb\n Racc_YY_Parse_Method = :_racc_yyparse_rb\n Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_R\n Racc_Runtime_Type = 'ruby'\n end\n\n def Parser.racc_runtime_type # :nodoc:\n Racc_Runtime_Type\n end\n\n def _racc_setup\n @yydebug = false unless self.class::Racc_debug_parser\n @yydebug = false unless defined?(@yydebug)\n if @yydebug\n @racc_debug_out = $stderr unless defined?(@racc_debug_out)\n @racc_debug_out ||= $stderr\n end\n arg = self.class::Racc_arg\n arg[13] = true if arg.size < 14\n arg\n end\n\n def _racc_init_sysvars\n @racc_state = [0]\n @racc_tstack = []\n @racc_vstack = []\n\n @racc_t = nil\n @racc_val = nil\n\n @racc_read_next = true\n\n @racc_user_yyerror = false\n @racc_error_status = 0\n end\n\n # The entry point of the parser. This method is used with #next_token.\n # If Racc wants to get token (and its value), calls next_token.\n #\n # Example:\n # def parse\n # @q = [[1,1],\n # [2,2],\n # [3,3],\n # [false, '$']]\n # do_parse\n # end\n #\n # def next_token\n # @q.shift\n # end\n class_eval <<~RUBY, __FILE__, __LINE__ + 1\n def do_parse\n \#{Racc_Main_Parsing_Routine}(_racc_setup(), false)\n end\n RUBY\n\n # The method to fetch next token.\n # If you use #do_parse method, you must implement #next_token.\n #\n # The format of return value is [TOKEN_SYMBOL, VALUE].\n # +token-symbol+ is represented by Ruby's symbol by default, e.g. :IDENT\n # for 'IDENT'. \";\" (String) for ';'.\n #\n # The final symbol (End of file) must be false.\n def next_token\n raise NotImplementedError, \"\#{self.class}\\#next_token is not defined\"\n end\n\n def _racc_do_parse_rb(arg, in_debug)\n action_table, action_check, action_default, action_pointer,\n _, _, _, _,\n _, _, token_table, * = arg\n\n _racc_init_sysvars\n tok = act = i = nil\n\n catch(:racc_end_parse) {\n while true\n if i = action_pointer[@racc_state[-1]]\n if @racc_read_next\n if @racc_t != 0 # not EOF\n tok, @racc_val = next_token()\n unless tok # EOF\n @racc_t = 0\n else\n @racc_t = (token_table[tok] or 1) # error token\n end\n racc_read_token(@racc_t, tok, @racc_val) if @yydebug\n @racc_read_next = false\n end\n end\n i += @racc_t\n unless i >= 0 and\n act = action_table[i] and\n action_check[i] == @racc_state[-1]\n act = action_default[@racc_state[-1]]\n end\n else\n act = action_default[@racc_state[-1]]\n end\n while act = _racc_evalact(act, arg)\n ;\n end\n end\n }\n end\n\n # Another entry point for the parser.\n # If you use this method, you must implement RECEIVER#METHOD_ID method.\n #\n # RECEIVER#METHOD_ID is a method to get next token.\n # It must 'yield' the token, which format is [TOKEN-SYMBOL, VALUE].\n class_eval <<~RUBY, __FILE__, __LINE__ + 1\n def yyparse(recv, mid)\n \#{Racc_YY_Parse_Method}(recv, mid, _racc_setup(), false)\n end\n RUBY\n\n def _racc_yyparse_rb(recv, mid, arg, c_debug)\n action_table, action_check, action_default, action_pointer,\n _, _, _, _,\n _, _, token_table, * = arg\n\n _racc_init_sysvars\n\n catch(:racc_end_parse) {\n until i = action_pointer[@racc_state[-1]]\n while act = _racc_evalact(action_default[@racc_state[-1]], arg)\n ;\n end\n end\n recv.__send__(mid) do |tok, val|\n unless tok\n @racc_t = 0\n else\n @racc_t = (token_table[tok] or 1) # error token\n end\n @racc_val = val\n @racc_read_next = false\n\n i += @racc_t\n unless i >= 0 and\n act = action_table[i] and\n action_check[i] == @racc_state[-1]\n act = action_default[@racc_state[-1]]\n end\n while act = _racc_evalact(act, arg)\n ;\n end\n\n while !(i = action_pointer[@racc_state[-1]]) ||\n ! @racc_read_next ||\n @racc_t == 0 # $\n unless i and i += @racc_t and\n i >= 0 and\n act = action_table[i] and\n action_check[i] == @racc_state[-1]\n act = action_default[@racc_state[-1]]\n end\n while act = _racc_evalact(act, arg)\n ;\n end\n end\n end\n }\n end\n\n ###\n ### common\n ###\n\n def _racc_evalact(act, arg)\n action_table, action_check, _, action_pointer,\n _, _, _, _,\n _, _, _, shift_n,\n reduce_n, * = arg\n nerr = 0 # tmp\n\n if act > 0 and act < shift_n\n #\n # shift\n #\n if @racc_error_status > 0\n @racc_error_status -= 1 unless @racc_t <= 1 # error token or EOF\n end\n @racc_vstack.push @racc_val\n @racc_state.push act\n @racc_read_next = true\n if @yydebug\n @racc_tstack.push @racc_t\n racc_shift @racc_t, @racc_tstack, @racc_vstack\n end\n\n elsif act < 0 and act > -reduce_n\n #\n # reduce\n #\n code = catch(:racc_jump) {\n @racc_state.push _racc_do_reduce(arg, act)\n false\n }\n if code\n case code\n when 1 # yyerror\n @racc_user_yyerror = true # user_yyerror\n return -reduce_n\n when 2 # yyaccept\n return shift_n\n else\n raise '[Racc Bug] unknown jump code'\n end\n end\n\n elsif act == shift_n\n #\n # accept\n #\n racc_accept if @yydebug\n throw :racc_end_parse, @racc_vstack[0]\n\n elsif act == -reduce_n\n #\n # error\n #\n case @racc_error_status\n when 0\n unless arg[21] # user_yyerror\n nerr += 1\n on_error @racc_t, @racc_val, @racc_vstack\n end\n when 3\n if @racc_t == 0 # is $\n # We're at EOF, and another error occurred immediately after\n # attempting auto-recovery\n throw :racc_end_parse, nil\n end\n @racc_read_next = true\n end\n @racc_user_yyerror = false\n @racc_error_status = 3\n while true\n if i = action_pointer[@racc_state[-1]]\n i += 1 # error token\n if i >= 0 and\n (act = action_table[i]) and\n action_check[i] == @racc_state[-1]\n break\n end\n end\n throw :racc_end_parse, nil if @racc_state.size <= 1\n @racc_state.pop\n @racc_vstack.pop\n if @yydebug\n @racc_tstack.pop\n racc_e_pop @racc_state, @racc_tstack, @racc_vstack\n end\n end\n return act\n\n else\n raise \"[Racc Bug] unknown action \#{act.inspect}\"\n end\n\n racc_next_state(@racc_state[-1], @racc_state) if @yydebug\n\n nil\n end\n\n def _racc_do_reduce(arg, act)\n _, _, _, _,\n goto_table, goto_check, goto_default, goto_pointer,\n nt_base, reduce_table, _, _,\n _, use_result, * = arg\n\n state = @racc_state\n vstack = @racc_vstack\n tstack = @racc_tstack\n\n i = act * -3\n len = reduce_table[i]\n reduce_to = reduce_table[i+1]\n method_id = reduce_table[i+2]\n void_array = []\n\n tmp_t = tstack[-len, len] if @yydebug\n tmp_v = vstack[-len, len]\n tstack[-len, len] = void_array if @yydebug\n vstack[-len, len] = void_array\n state[-len, len] = void_array\n\n # tstack must be updated AFTER method call\n if use_result\n vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0])\n else\n vstack.push __send__(method_id, tmp_v, vstack)\n end\n tstack.push reduce_to\n\n racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug\n\n k1 = reduce_to - nt_base\n if i = goto_pointer[k1]\n i += state[-1]\n if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1\n return curstate\n end\n end\n goto_default[k1]\n end\n\n # This method is called when a parse error is found.\n #\n # ERROR_TOKEN_ID is an internal ID of token which caused error.\n # You can get string representation of this ID by calling\n # #token_to_str.\n #\n # ERROR_VALUE is a value of error token.\n #\n # value_stack is a stack of symbol values.\n # DO NOT MODIFY this object.\n #\n # This method raises ParseError by default.\n #\n # If this method returns, parsers enter \"error recovering mode\".\n def on_error(t, val, vstack)\n raise ParseError, sprintf(\"parse error on value %s (%s)\",\n val.inspect, token_to_str(t) || '?')\n end\n\n # Enter error recovering mode.\n # This method does not call #on_error.\n def yyerror\n throw :racc_jump, 1\n end\n\n # Exit parser.\n # Return value is +Symbol_Value_Stack[0]+.\n def yyaccept\n throw :racc_jump, 2\n end\n\n # Leave error recovering mode.\n def yyerrok\n @racc_error_status = 0\n end\n\n # For debugging output\n def racc_read_token(t, tok, val)\n @racc_debug_out.print 'read '\n @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') '\n @racc_debug_out.puts val.inspect\n @racc_debug_out.puts\n end\n\n def racc_shift(tok, tstack, vstack)\n @racc_debug_out.puts \"shift \#{racc_token2str tok}\"\n racc_print_stacks tstack, vstack\n @racc_debug_out.puts\n end\n\n def racc_reduce(toks, sim, tstack, vstack)\n out = @racc_debug_out\n out.print 'reduce '\n if toks.empty?\n out.print ' <none>'\n else\n toks.each {|t| out.print ' ', racc_token2str(t) }\n end\n out.puts \" --> \#{racc_token2str(sim)}\"\n racc_print_stacks tstack, vstack\n @racc_debug_out.puts\n end\n\n def racc_accept\n @racc_debug_out.puts 'accept'\n @racc_debug_out.puts\n end\n\n def racc_e_pop(state, tstack, vstack)\n @racc_debug_out.puts 'error recovering mode: pop token'\n racc_print_states state\n racc_print_stacks tstack, vstack\n @racc_debug_out.puts\n end\n\n def racc_next_state(curstate, state)\n @racc_debug_out.puts \"goto \#{curstate}\"\n racc_print_states state\n @racc_debug_out.puts\n end\n\n def racc_print_stacks(t, v)\n out = @racc_debug_out\n out.print ' ['\n t.each_index do |i|\n out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')'\n end\n out.puts ' ]'\n end\n\n def racc_print_states(s)\n out = @racc_debug_out\n out.print ' ['\n s.each {|st| out.print ' ', st }\n out.puts ' ]'\n end\n\n def racc_token2str(tok)\n self.class::Racc_token_to_s_table[tok] or\n raise \"[Racc Bug] can't convert token \#{tok} to string\"\n end\n\n # Convert internal ID of token symbol to the string.\n def token_to_str(t)\n self.class::Racc_token_to_s_table[t]\n end\n\n end\n\nend\n#++\n\n"