#lang racket ;;; parser2.rkt - Sections 15.3 du chapitre 15 (Analyseurs Syntaxiques) ;;; Livre PCPS : "Premiers Cours de Programmation avec Scheme" ;;; Langage determine par le source (require parser-tools/lex) (require parser-tools/yacc) (require "show.rkt") ; pour les tests ;;; E --> E * E E --> E + E E --> (E) E--> int ;;; le lexeur (define-lex-abbrevs (entier (repetition 1 +inf.0 (char-range "0" "9")))) (define-tokens value-tokens (NUM)) (define-empty-tokens op-tokens (LPAR RPAR + * FINI)) (define get-lexeme (lexer [(eof) 'FINI] [(union "+" "*") (string->symbol lexeme)] ["(" 'LPAR] ; Left PARenthesis [")" 'RPAR] ; Right PARenthesis [entier (token-NUM (string->number lexeme))])) ; un entier ou un flottant est un nombre (define parse (parser (start expr) (end FINI) (tokens value-tokens op-tokens) (error (lambda (a b c) (printf "Erreur d'analyse : ~a\n" (list a b c)))) (precs (left +) (left *)) ; sans cette ligne l'analyse de "2*3+4" est fausse ! (grammar (expr [(NUM) $1] [(expr * expr) (* $1 $3)] [(expr + expr) (+ $1 $3)] [(LPAR expr RPAR) $2])))) (define (parseur str) (let ((p (open-input-string str))) (parse (lambda () (get-lexeme p))))) (show (parseur "2+3*4")) (show (parseur "2*(1+3)+4")) (show (parseur "2*((1+3)*5)+4")) (show (parseur "2*3+4"))