; 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. ; ; Divers pre-traitements avant l'ecriture des tables ; ; Passe d'un arc multi-range a une liste d'arcs mono-range (define prep-arc->sharcs (lambda (arc) (let* ((range-l (car arc)) (dest (cdr arc)) (op (lambda (range) (cons range dest)))) (map op range-l)))) ; Compare des arcs courts selon leur premier caractere (define prep-sharc-<= (lambda (sharc1 sharc2) (class-<= (caar sharc1) (caar sharc2)))) ; Remplit les trous parmi les sharcs avec des arcs "erreur" (define prep-fill-error (lambda (sharcs) (let loop ((sharcs sharcs) (start 'inf-)) (cond ((class-= start 'inf+) '()) ((null? sharcs) (cons (cons (cons start 'inf+) 'err) (loop sharcs 'inf+))) (else (let* ((sharc (car sharcs)) (h (caar sharc)) (t (cdar sharc))) (if (class-< start h) (cons (cons (cons start (- h 1)) 'err) (loop sharcs h)) (cons sharc (loop (cdr sharcs) (if (class-= t 'inf+) 'inf+ (+ t 1))))))))))) ; ; Passe d'une liste d'arcs a un arbre de decision ; ; 1ere methode: seulement des comparaisons < ; (define prep-arcs->tree ; (lambda (arcs) ; (let* ((sharcs-l (map prep-arc->sharcs arcs)) ; (sharcs (apply append sharcs-l)) ; (sorted-with-holes (merge-sort sharcs prep-sharc-<=)) ; (sorted (prep-fill-error sorted-with-holes)) ; (op (lambda (sharc) (cons (caar sharc) (cdr sharc)))) ; (table (list->vector (map op sorted)))) ; (let loop ((left 0) (right (- (vector-length table) 1))) ; (if (= left right) ; (cdr (vector-ref table left)) ; (let ((mid (quotient (+ left right 1) 2))) ; (list (car (vector-ref table mid)) ; (loop left (- mid 1)) ; (loop mid right)))))))) ; Passe d'une liste d'arcs a un arbre de decision ; 2eme methode: permettre des comparaisons = quand ca adonne (define prep-arcs->tree (lambda (arcs) (let* ((sharcs-l (map prep-arc->sharcs arcs)) (sharcs (apply append sharcs-l)) (sorted-with-holes (merge-sort sharcs prep-sharc-<=)) (sorted (prep-fill-error sorted-with-holes)) (op (lambda (sharc) (cons (caar sharc) (cdr sharc)))) (table (list->vector (map op sorted)))) (let loop ((left 0) (right (- (vector-length table) 1))) (if (= left right) (cdr (vector-ref table left)) (let ((mid (quotient (+ left right 1) 2))) (if (and (= (+ left 2) right) (= (+ (car (vector-ref table mid)) 1) (car (vector-ref table right))) (eqv? (cdr (vector-ref table left)) (cdr (vector-ref table right)))) (list '= (car (vector-ref table mid)) (cdr (vector-ref table mid)) (cdr (vector-ref table left))) (list (car (vector-ref table mid)) (loop left (- mid 1)) (loop mid right))))))))) ; Determine si une action a besoin de calculer yytext (define prep-detect-yytext (lambda (s) (let loop1 ((i (- (string-length s) 6))) (cond ((< i 0) #f) ((char-ci=? (string-ref s i) #\y) (let loop2 ((j 5)) (cond ((= j 0) #t) ((char-ci=? (string-ref s (+ i j)) (string-ref "yytext" j)) (loop2 (- j 1))) (else (loop1 (- i 1)))))) (else (loop1 (- i 1))))))) ; Note dans une regle si son action a besoin de yytext (define prep-set-rule-yytext? (lambda (rule) (let ((action (get-rule-action rule))) (set-rule-yytext? rule (prep-detect-yytext action))))) ; Note dans toutes les regles si leurs actions ont besoin de yytext (define prep-set-rules-yytext? (lambda (rules) (let loop ((n (- (vector-length rules) 1))) (if (>= n 0) (begin (prep-set-rule-yytext? (vector-ref rules n)) (loop (- n 1)))))))