; SILex - Scheme Implementation of Lex ; Copyright (C) 2001 Danny Dube' ; ; This program 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 2 ; of the License, or (at your option) any later version. ; ; This program 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, write to the Free Software ; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ; ; Gestion d'erreurs ; (define lex-exit-continuation #f) (define lex-unwind-protect-list '()) (define lex-error-filename #f) (define lex-unwind-protect (lambda (proc) (set! lex-unwind-protect-list (cons proc lex-unwind-protect-list)))) (define lex-error (lambda (line column . l) (let* ((linestr (if line (number->string line) #f)) (colstr (if column (number->string column) #f)) (namelen (string-length lex-error-filename)) (linelen (if line (string-length linestr) -1)) (collen (if column (string-length colstr) -1)) (totallen (+ namelen 1 linelen 1 collen 2))) (display "Lex error:") (newline) (display lex-error-filename) (if line (begin (display ":") (display linestr))) (if column (begin (display ":") (display colstr))) (display ": ") (let loop ((l l)) (if (null? l) (newline) (let ((item (car l))) (display item) (if (equal? '#\newline item) (let loop2 ((i totallen)) (if (> i 0) (begin (display #\space) (loop2 (- i 1)))))) (loop (cdr l))))) (newline) (let loop ((l lex-unwind-protect-list)) (if (pair? l) (begin ((car l)) (loop (cdr l))))) (lex-exit-continuation #f)))) ; ; Decoupage des arguments ; (define lex-recognized-args '(complete-driver? filein table-name fileout counters portable code pp)) (define lex-valued-args '(complete-driver? filein table-name fileout counters)) (define lex-parse-args (lambda (args) (let loop ((args args)) (if (null? args) '() (let ((sym (car args))) (cond ((not (symbol? sym)) (lex-error #f #f "bad option list.")) ((not (memq sym lex-recognized-args)) (lex-error #f #f "unrecognized option \"" sym "\".")) ((not (memq sym lex-valued-args)) (cons (cons sym '()) (loop (cdr args)))) ((null? (cdr args)) (lex-error #f #f "the value of \"" sym "\" not specified.")) (else (cons (cons sym (cadr args)) (loop (cddr args)))))))))) ; ; Differentes etapes de la fabrication de l'automate ; (define lex1 (lambda (filein) ; (display "lex1: ") (write (get-internal-run-time)) (newline) (parser filein))) (define lex2 (lambda (filein) (let* ((result (lex1 filein)) (<<EOF>>-action (car result)) (<<ERROR>>-action (cadr result)) (rules (cddr result))) ; (display "lex2: ") (write (get-internal-run-time)) (newline) (append (list <<EOF>>-action <<ERROR>>-action rules) (re2nfa rules))))) (define lex3 (lambda (filein) (let* ((result (lex2 filein)) (<<EOF>>-action (list-ref result 0)) (<<ERROR>>-action (list-ref result 1)) (rules (list-ref result 2)) (nl-start (list-ref result 3)) (no-nl-start (list-ref result 4)) (arcs (list-ref result 5)) (acc (list-ref result 6))) ; (display "lex3: ") (write (get-internal-run-time)) (newline) (append (list <<EOF>>-action <<ERROR>>-action rules) (noeps nl-start no-nl-start arcs acc))))) (define lex4 (lambda (filein) (let* ((result (lex3 filein)) (<<EOF>>-action (list-ref result 0)) (<<ERROR>>-action (list-ref result 1)) (rules (list-ref result 2)) (nl-start (list-ref result 3)) (no-nl-start (list-ref result 4)) (arcs (list-ref result 5)) (acc (list-ref result 6))) ; (display "lex4: ") (write (get-internal-run-time)) (newline) (append (list <<EOF>>-action <<ERROR>>-action rules) (sweep nl-start no-nl-start arcs acc))))) (define lex5 (lambda (filein) (let* ((result (lex4 filein)) (<<EOF>>-action (list-ref result 0)) (<<ERROR>>-action (list-ref result 1)) (rules (list-ref result 2)) (nl-start (list-ref result 3)) (no-nl-start (list-ref result 4)) (arcs (list-ref result 5)) (acc (list-ref result 6))) ; (display "lex5: ") (write (get-internal-run-time)) (newline) (append (list <<EOF>>-action <<ERROR>>-action rules) (nfa2dfa nl-start no-nl-start arcs acc))))) (define lex6 (lambda (args-alist) (let* ((filein (cdr (assq 'filein args-alist))) (result (lex5 filein)) (<<EOF>>-action (list-ref result 0)) (<<ERROR>>-action (list-ref result 1)) (rules (list-ref result 2)) (nl-start (list-ref result 3)) (no-nl-start (list-ref result 4)) (arcs (list-ref result 5)) (acc (list-ref result 6))) ; (display "lex6: ") (write (get-internal-run-time)) (newline) (prep-set-rules-yytext? rules) (output args-alist <<EOF>>-action <<ERROR>>-action rules nl-start no-nl-start arcs acc) #t))) (define lex7 (lambda (args) (call-with-current-continuation (lambda (exit) (set! lex-exit-continuation exit) (set! lex-unwind-protect-list '()) (set! lex-error-filename (cadr (memq 'filein args))) (let* ((args-alist (lex-parse-args args)) (result (lex6 args-alist))) ; (display "lex7: ") (write (get-internal-run-time)) (newline) result))))) ; ; Fonctions principales ; (define lex (lambda (filein fileout . options) (lex7 (append (list 'complete-driver? #t 'filein filein 'table-name "lexer-default-table" 'fileout fileout) options)))) (define lex-tables (lambda (filein table-name fileout . options) (lex7 (append (list 'complete-driver? #f 'filein filein 'table-name table-name 'fileout fileout) options))))