[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
source tracking for nyacc parser is coming
From: |
Matt Wette |
Subject: |
source tracking for nyacc parser is coming |
Date: |
Fri, 22 Oct 2021 06:00:09 -0700 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.1.2 |
Hi All,
I just wanted to give an update on this requested feature for nyacc.
I've been working on adding source location tracking to nyacc's
parser. I believe I have a working implementation. It should
appear in future release 1.06.0 (vs latest release 1.05.0). If
you want to work with it it's on the dev-1.06 branch in git
(i.e., git://git.savannah.nongnu.org/nyacc.git). The parser
code, with annotations "=>" indicating changes, is shown below.
To demonstrate, I have implemented it in a language I'm working
on called TCLish. In nyacc, the lexical analyzer returns pairs
(token-type . token-value). I attach source-properties to these
pairs. The parser is able to propapate them through the parsing
phase. In the AST-to-tree-IL phase I transfer the source-properties
to the external tree-IL representation. Guile takes care of the
rest. (Note: in the lexical analyzer, I'm not bothering to
trace column: that gets set to zero.)
I generated the file, demo.tsh, with contents:
proc baz { } {
puts 1 2 3
}
proc bar { } {
set x (1 + 2)
baz
}
proc foo { } {
set x (3 + 4)
bar
}
Now I run the tsh interpreter and source demo.tsh, then call "foo":
scheme@(guile-user)> ,L nx-tsh
Happy hacking with nx-tsh! To switch back, type `,L scheme'.
nx-tsh@(guile-user)> source "demo.tsh"
nx-tsh@(guile-user)> foo
ice-9/boot-9.scm:1685:16: In procedure raise-exception:
In procedure string=: Wrong type argument in position 1 (expecting string):
1
Entering a new prompt. Type `,bt' for a backtrace or `,q' to continue.
nx-tsh@(guile-user) [1]> ,bt
In demo.tsh:
13:0 5 (foo) <= line number traceback
8:0 4 (bar) <= line number traceback
3:0 3 (baz) <= line number traceback
In nyacc/lang/tsh/xlib.scm:
81:12 2 (tsh:puts _ _ _)
In unknown file:
1 (string=? 1 "-nonewline")
In ice-9/boot-9.scm:
1685:16 0 (raise-exception _ #:continuable? _)
Here is the updated code for the (numeric) parser,
with new/mod lines denoted with `=>':
(define* (make-lalr-parser/num mach #:key (skip-if-unexp '()) interactive env)
(let* ((len-v (assq-ref mach 'len-v))
(rto-v (assq-ref mach 'rto-v))
(pat-v (assq-ref mach 'pat-v))
(xct-v (make-xct (assq-ref mach 'act-v) env))
(ntab (assq-ref mach 'ntab))
(start (assq-ref (assq-ref mach 'mtab) '$start)))
(lambda* (lexr #:key debug)
(let loop ((state (list 0)) ; state stack
(stack (list '$@)) ; semantic value stack
(nval #f) ; non-terminal from prev reduction
(lval #f)) ; lexical value (from lex'r)
(cond
((and interactive nval
(eqv? (car nval) start)
(zero? (car state))) ; done
(cdr nval))
((not (or nval lval))
(if (eqv? $default (caar (vector-ref pat-v (car state))))
=> (loop state stack (cons-source stack $default #f) lval)
(loop state stack nval (lexr)))) ; reload
(else
(let* ((laval (or nval lval))
(tval (car laval))
(sval (cdr laval))
(stxl (vector-ref pat-v (car state)))
(stx (or (assq-ref stxl tval)
(and (not (memq tval skip-if-unexp))
(assq-ref stxl $default))
#f))) ; error
(if debug (dmsg/n (car state) (if nval tval sval) stx ntab))
(cond
((eq? #f stx) ; error
(if (memq tval skip-if-unexp)
(loop state stack #f #f)
(parse-error state laval)))
((negative? stx) ; reduce
(let* ((gx (abs stx))
(gl (vector-ref len-v gx))
($$ (apply (vector-ref xct-v gx) stack))
=> (pobj (if (zero? gl) laval (list-tail stack (1- gl))))
=> (pval (source-properties pobj))
=> (tval (cons-source pobj (vector-ref rto-v gx) $$)))
=> (if (supports-source-properties? $$)
=> (set-source-properties! $$ pval))
(loop (list-tail state gl) (list-tail stack gl) tval lval)))
((positive? stx) ; shift
=> (loop (cons stx state) (cons-source laval sval stack)
#f (if nval lval #f)))
(else ; accept
(car stack))))))))))
Matt
- source tracking for nyacc parser is coming,
Matt Wette <=