When parsing fails, you want to display the failed position as follows, right?
parse error: line 2, col 5
foo bar
    ^
Since it is short, I will paste it all for the time being.
# parser.y
class Parser
rule
  program: "a" "b" "c" "d" ";"
  {
    puts "program found"
    result = val
  }
end
---- header
TokenValue = Struct.new(:value, :pos)
---- inner
def initialize(src, tokens)
  @src = src
  @tokens = tokens
end
def next_token
  @tokens.shift
end
def parse
  do_parse
end
def get_lineno_and_range(pos)
  lineno = 1
  line_start = 0
  range = nil
  @src.each_line do |line|
    next_line_start = line_start + line.size
    range = line_start .. (next_line_start - 1)
    break if range.include?(pos)
    line_start = next_line_start
    lineno += 1
  end
  [lineno, range]
end
def on_error(token_id, val, vstack)
  lineno, range = get_lineno_and_range(val.pos)
  colno = val.pos - range.begin + 1
  line = @src[range]
  puts "parse error: line #{lineno}, col #{colno}"
  puts line
  print " " * (colno - 1), "^\n"
end
---- footer
def tokenize(src)
  tokens = []
  pos = 0
  while pos < src.size
    c = src[pos]
    case c
    when /\s/
      pos += 1
    else
      tokens << [c, TokenValue.new(c, pos)]
      pos += 1
    end
  end
  tokens
end
src = File.read(ARGV[0])
tokens = tokenize(src)
parser = Parser.new(src, tokens)
result = parser.parse()
puts "result: " + result.inspect
A parser that accepts only the token sequence a`` b c`` d ;.
In the input source code, separate tokens with spaces or line breaks.
Successful parsing example:
a
b
c d
;
For example, if you give the following source code with d replaced with X, parsing will fail.
a
b
c X
;
Execution example when it fails:
$ racc parser.y -o parser.rb
$ ruby parser.rb sample_ng.txt
parse error: line 4, col 3
c X
  ^
result: nil
It's short, so I think it's faster to read the code pasted above, but it's a quick note.
--The token value should have the start position of the token (the number of characters in the original source code).
--Keep the original source code as Parser # src
--If parsing fails, use Parser # src and the starting position of the failed token
Determining lines and columns on the original source code
All symbols, terminating / non-terminal, have a corresponding value (or semantic value in a cool way) that can be used to exchange information. (Omitted) You can use any one Ruby object you like as a value, which is synonymous with * sending anything *.
"Book for using Ruby 256 times (Amazon)" p46
So, in the above, we are using an instance of the TokenValue class as the token value.
-Ruby/Racc: Visualize stack movement during parsing like FlameGraph
The following is not related to Racc, but it is related to Ruby + parser.
-I made a simple compiler for my own language in Ruby -I made an expr command with only four arithmetic operations and remainders in Ruby -Regular expression engine (Rob Pike's backtrack implementation) copied in Ruby