From: Joel Reymont
Subject: Parsing and reporting error location
Date: 
Message-ID: <1177284606.192046.122270@n59g2000hsh.googlegroups.com>
Folks,

Has anyone gotten cl-yacc to report error location (line and column
range)?

I browsed the source code but couldn't find such functionality.

How would I go about implementing this myself? I'm spoiled by
ocamlyacc and Parsec (Haskell) that have this built-in.

    Thanks, Joel

From: Richard M Kreuter
Subject: Re: Parsing and reporting error location
Date: 
Message-ID: <87odlfdgvm.fsf@tan-ru.localdomain>
Joel Reymont <······@gmail.com> writes:

> Folks,
>
> Has anyone gotten cl-yacc to report error location (line and column
> range)?
>
> I browsed the source code but couldn't find such functionality.

I've done something like this in the past with cl-yacc, using a Gray
Streams class to keep track of the tokenizer's position in the stream.
A rudimentary Gray Streams class for this purpose is available in the
SBCL manual [1], and the relevant cl-yacc code went something like
this:

(define-condition yacc-parse-error-with-position (yacc-parse-error)
  ((stream-line-number :initarg :stream-line-number
                       :reader yacc-parse-error-with-position-line-number)
   (stream-column-number :initarg :stream-column-number
                         :reader
                         yacc-parse-error-with-position-column-number))
  (:report (lambda (e stream)
            (format stream "~<Unexpected terminal ~S (value ~S)~
                            Expected one of: ~S~
                            Line number ~D~
                            Column number ···@:>"
                     (yacc-parse-error-terminal e)
                     (yacc-parse-error-value e)
                     (yacc-parse-error-expected-terminals e)
                     (yacc-parse-error-with-position-line-number e)
                     (yacc-parse-error-with-position-column-number e)))))

;; *STREAM* is your real input stream, *LEXER* is your lexer function,
;; *PARSER* is your parser.
(let ((counting-stream
       (make-instance 'counting-character-input-stream
		      :stream *stream*)))
  (handler-bind
      ((yacc-parse-error
	#'(lambda (error)
	    (error 'yacc-parse-error-with-position
		   :terminal (yacc-parse-error-terminal error)
		   :value (yacc-parse-error-value error)
		   :expected-terminals (yacc-parse-error-expected-terminals 
					error)
		   :stream-line-number (line-count-of counting-stream)
		   :stream-column-number (col-count-of counting-stream)))))
    (parse-with-lexer *lexer* *parser*))) 

Hope that helps,
RmK


[1] http://www.sbcl.org/manual/Character-counting-input-stream.html#Character-counting-input-stream
From: Joel Reymont
Subject: Re: Parsing and reporting error location
Date: 
Message-ID: <1177315698.798094.148890@p77g2000hsh.googlegroups.com>
On Apr 23, 2:22 am, Richard M Kreuter <·······@progn.net> wrote:
> Hope that helps,
> RmK

It does, thanks!