Class: Racc::GrammarFileScanner
Relationships & Source Files | |
Inherits: | Object |
Defined in: | lib/racc/grammarfileparser.rb |
Constant Summary
-
CACHE =
# File 'lib/racc/grammarfileparser.rb', line 654{}
-
LEFT_TO_RIGHT =
# File 'lib/racc/grammarfileparser.rb', line 647{ '(' => ')', '{' => '}', '[' => ']', '<' => '>' }
-
ReservedWord =
# File 'lib/racc/grammarfileparser.rb', line 488{ 'right' => :RIGHT, 'left' => :LEFT, 'nonassoc' => :NONASSOC, 'preclow' => :PRECLOW, 'prechigh' => :PRECHIGH, 'token' => :TOKEN, 'convert' => :CONV, 'options' => :OPTION, 'start' => :START, 'expect' => :EXPECT, 'error_on_expect_mismatch' => :ERROR_ON_EXPECT_MISMATCH, 'class' => :CLASS, 'rule' => :RULE, 'end' => :END }
Class Method Summary
- .new(str, filename = '-') ⇒ GrammarFileScanner constructor
Instance Attribute Summary
Instance Method Summary
- #lineno
- #yylex(&block)
- #atom_symbol(token) private
- #get_quoted_re(left) private
- #literal_head?(pre, post) ⇒ Boolean private
- #next_line private
- #read(len) private
- #reads(re) private
- #scan_action private
- #scan_error!(msg) private
- #scan_quoted(left, tag = 'string') private
- #skip_comment private
- #yylex0 {|nil| ... } private
Constructor Details
.new(str, filename = '-') ⇒ GrammarFileScanner
# File 'lib/racc/grammarfileparser.rb', line 403
def initialize(str, filename = '-') @lines = str.b.split(/\n|\r\n|\r/) @filename = filename @lineno = -1 @line_head = true @in_rule_blk = false @in_conv_blk = false @in_block = nil @epilogue = '' @debug = false next_line end
Instance Attribute Details
#debug (rw)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 422
attr_accessor :debug
#epilogue (readonly)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 416
attr_reader :epilogue
Instance Method Details
#atom_symbol(token) (private)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 505
def atom_symbol(token) if token == 'end' symbol = :END @in_conv_blk = false @in_rule_blk = false else if @line_head and not @in_conv_blk and not @in_rule_blk symbol = ReservedWord[token] || :SYMBOL else symbol = :SYMBOL end case symbol when :RULE then @in_rule_blk = true when :CONV then @in_conv_blk = true end end @line_head = false symbol end
#get_quoted_re(left) (private)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 656
def get_quoted_re(left) term = Regexp.quote(LEFT_TO_RIGHT[left] || left) CACHE[left] ||= /\A[^#{term}\\]*(?:\\.[^\\#{term}]*)*#{term}/ end
#lineno
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 418
def lineno @lineno + 1 end
#literal_head?(pre, post) ⇒ Boolean
(private)
# File 'lib/racc/grammarfileparser.rb', line 612
def literal_head?(pre, post) (!pre || /[a-zA-Z_0-9]/n !~ pre[-1,1]) && !post.empty? && /\A[\s\=]/n !~ post end
#next_line (private)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 469
def next_line @lineno += 1 @line = @lines[@lineno] if not @line or /\A----/ =~ @line @epilogue = @lines.join("\n") @lines.clear @line = nil if @in_block @lineno -= 1 scan_error! sprintf('unterminated %s', @in_block) end false else @line.sub!(/(?:\n|\r\n|\r)\z/, '') @line_head = true true end end
#read(len) (private)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 617
def read(len) s = @line[0, len] @line = @line[len .. -1] s end
#reads(re) (private)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 623
def reads(re) m = re.match(@line) or return nil @line = m.post_match m[0] end
#scan_action (private)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 536
def scan_action buf = String.new nest = 1 pre = nil @in_block = 'action' begin pre = nil if s = reads(/\A\s+/) # does not set 'pre' buf << s end until @line.empty? if s = reads(/\A[^'"`{}%#\/\$]+/) buf << (pre = s) next end case ch = read(1) when '{' nest += 1 buf << (pre = ch) when '}' nest -= 1 if nest == 0 @in_block = nil buf.sub!(/[ \t\f]+\z/, '') return buf end buf << (pre = ch) when '#' # comment buf << ch << @line break when "'", '"', '`' buf << (pre = scan_quoted(ch)) when '%' if literal_head? pre, @line # % string, regexp, array buf << ch case ch = read(1) when /[qQx]/n buf << ch << (pre = scan_quoted(read(1), '%string')) when /wW/n buf << ch << (pre = scan_quoted(read(1), '%array')) when /s/n buf << ch << (pre = scan_quoted(read(1), '%symbol')) when /r/n buf << ch << (pre = scan_quoted(read(1), '%regexp')) when /[a-zA-Z0-9= ]/n # does not include "_" scan_error! "unknown type of % literal '%#{ch}'" else buf << (pre = scan_quoted(ch, '%string')) end else # operator buf << '||op->' if $raccs_print_type buf << (pre = ch) end when '/' if literal_head? pre, @line # regexp buf << (pre = scan_quoted(ch, 'regexp')) else # operator buf << '||op->' if $raccs_print_type buf << (pre = ch) end when '$' # gvar buf << ch << (pre = read(1)) else raise 'racc: fatal: must not happen' end end buf << "\n" end while next_line() raise 'racc: fatal: scan finished before parser finished' end
#scan_error!(msg) (private)
# File 'lib/racc/grammarfileparser.rb', line 661
def scan_error!(msg) raise CompileError, "#{lineno()}: #{msg}" end
#scan_quoted(left, tag = 'string') (private)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 629
def scan_quoted(left, tag = 'string') buf = left.dup buf = "||#{tag}->" + buf if $raccs_print_type re = get_quoted_re(left) sv, @in_block = @in_block, tag begin if s = reads(re) buf << s break else buf << @line end end while next_line() @in_block = sv buf << "<-#{tag}||" if $raccs_print_type buf end
#skip_comment (private)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 525
def skip_comment @in_block = 'comment' until m = /\*\//.match(@line) next_line end @line = m.post_match @in_block = nil end
#yylex(&block)
[ GitHub ]#yylex0 {|nil| ... } (private)
# File 'lib/racc/grammarfileparser.rb', line 437
def yylex0 begin until @line.empty? @line.sub!(/\A\s+/, '') if /\A\#/ =~ @line break elsif /\A\/\*/ =~ @line skip_comment elsif s = reads(/\A[a-zA-Z_]\w*/) yield [atom_symbol(s), s.intern] elsif s = reads(/\A\d+/) yield [:DIGIT, s.to_i] elsif ch = reads(/\A./) case ch when '"', "'" yield [:STRING, eval(scan_quoted(ch))] when '{' lineno = lineno() yield [:ACTION, SourceText.new(scan_action(), @filename, lineno)] else if ch == '|' @line_head = false end yield [ch, ch] end else end end end while next_line() yield nil end