From: Jan Nieuwenhuizen <janneke@gnu.org>
To: NalaGinrut@gmail.com
Cc: guile-user@gnu.org
Subject: lalr parser: on Bison-like source locations
Date: Sun, 26 Oct 2014 21:11:06 +0100 [thread overview]
Message-ID: <8738aazj51.fsf@drakenvlieg.flower> (raw)
[-- Attachment #1: Type: text/plain, Size: 763 bytes --]
Hi,
Saw your question on irc.
Attached is a modification on your `simple' language that demonstrates
transparent source locations.
The explicit, Bison-like locations work just like they do in Bison...eg
something like:
;; helper
(define (note-location ast loc)
(when (supports-source-properties? ast)
(set-source-property! ast 'loc loc))
ast)
(define (make-parser)
(lalr-parser
;; ...
;; production rules
(variable
(type Identifier = expression semicolon) : `(variable ,$2 ,$1 ,(note-location `(expression ,$4) @3))
(Identifier dot Identifier Identifier = expression semicolon) : `(variable ,$4 (type ,$3 ,$1) ,(note-location `(expression ,$6) @5)))
Does that answer your question?
Greetings, Jan
[-- Attachment #2: simple.scm --]
[-- Type: application/octet-stream, Size: 3562 bytes --]
;; Copyright (C) 2014
;; "Mu Lei" known as "NalaGinrut" <NalaGinrut@gmail.com>
;; This file is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
(define-module (language simple simple)
#:use-module (system base lalr)
#:use-module (language tree-il)
#:use-module (ice-9 and-let-star)
#:use-module (ice-9 match)
#:export (make-simple-tokenizer make-parser compile-tree-il))
;; Two helper macros to create the token struct for returning
(define-syntax-rule (port-source-location port)
(make-source-location (port-filename port)
(port-line port)
(port-column port)
(false-if-exception (ftell port))
#f))
(define-syntax-rule (return port category value)
(make-lexical-token category (port-source-location port) value))
(define (is-whitespace? c) (char-set-contains? char-set:whitespace c))
(define (is-number? c) (char-set-contains? char-set:hex-digit c))
;; operators, in this simple case, we just have four operators
(define (is-op? c) (string-contains "+-*/" (string c)))
(define (is-delimiter? c)
(or (eof-object? c) (string-contains " +-*/;\n" (string c))))
(define (get-number port)
(let lp((c (peek-char port)) (ret '()))
(cond
((is-delimiter? c) ; encounter delimiter, finish to read a number
;; convert to a number representation
(string->number (list->string (reverse ret))))
(else
(read-char port) ; next char
(lp (peek-char port) (cons c ret))))))
(define (get-op port) (string->symbol (string (read-char port))))
(define (next-token port)
(let ((c (peek-char port)))
(cond
((or (eof-object? c) (char=? c #\nl)) ; end of line, or end src
'*eoi*) ; return '*eoi* because LALR module need it
((is-whitespace? c)
(read-char port)
(next-token port)) ; skip white space
((is-number? c)
(return port 'number (get-number port)))
((is-op? c)
(return port (get-op port) #f))
(else
(read-char port)
(next-token port)))))
(define (make-simple-tokenizer port) (lambda () (next-token port)))
(define (make-parser)
(lalr-parser
(driver: lr)
;;(driver: glr)
(number (left: + -) (left: * /))
(program (exp) : $1
(*eoi*) : (call-with-input-string "" read)) ; *eof-object*
(exp (exp + term) : `(+ ,$1 ,$3)
(exp - term) : `(- ,$1 ,$3)
(term) : $1)
(term (term * factor) : `(* ,$1 ,$3)
(term / factor) : `(/ ,$1 ,$3)
(factor) : $1)
(factor (number) : `(number ,$1))))
(define (compile-tree-il exp env opts)
(values (parse-tree-il (comp exp '())) env env))
(define (comp src e)
(and-let* (((supports-source-properties? src))
(loc (source-property src 'loc)))
(format (current-error-port) "LOC [~a]: ~a\n" loc src))
(match src
(('number x) `(const ,x))
((op x y) `(apply (primitive ,op) ,(comp x e) ,(comp y e)))
((h t ...) (comp h e)))) ;; for driver glr
[-- Attachment #3: spec.scm --]
[-- Type: application/octet-stream, Size: 1097 bytes --]
;; Copyright (C) 2014
;; "Mu Lei" known as "NalaGinrut" <NalaGinrut@gmail.com>
;; This file is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
(define-module (language simple spec)
#:use-module (system base language)
#:use-module (language simple simple)
#:export (simple))
(define-language simple
#:title "simple"
#:reader (lambda (port env)
((make-parser) (make-simple-tokenizer port) error))
#:compilers `((tree-il . ,compile-tree-il))
#:printer write)
[-- Attachment #4: Type: text/plain, Size: 154 bytes --]
--
Jan Nieuwenhuizen <janneke@gnu.org> | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | Avatar® http://AvatarAcademy.nl
next reply other threads:[~2014-10-26 20:11 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-26 20:11 Jan Nieuwenhuizen [this message]
2014-10-28 10:11 ` lalr parser: on Bison-like source locations Nala Ginrut
2014-10-28 10:41 ` Jan Nieuwenhuizen
2014-10-28 10:51 ` Nala Ginrut
2014-10-28 16:19 ` Ludovic Courtès
2014-10-28 22:17 ` Ludovic Courtès
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8738aazj51.fsf@drakenvlieg.flower \
--to=janneke@gnu.org \
--cc=NalaGinrut@gmail.com \
--cc=guile-user@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).