Advertisement
Guest User

Untitled

a guest
May 13th, 2018
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 4.32 KB | None | 0 0
  1. #lang racket
  2.  
  3. (require "calc.rkt")
  4.  
  5. (define (def-name p)
  6.   (car p))
  7.  
  8. (define (def-prods p)
  9.   (cdr p))
  10.  
  11. (define (rule-name r)
  12.   (car r))
  13.  
  14. (define (rule-body r)
  15.   (cdr r))
  16.  
  17. (define (lookup-def g nt)
  18.   (cond [(null? g) (error "unknown non-terminal" g)]
  19.         [(eq? (def-name (car g)) nt) (def-prods (car g))]
  20.         [else (lookup-def (cdr g) nt)]))
  21.  
  22. (define parse-error 'PARSEERROR)
  23.  
  24. (define (parse-error? r) (eq? r 'PARSEERROR))
  25.  
  26. (define (res v r)
  27.   (cons v r))
  28.  
  29. (define (res-val r)
  30.   (car r))
  31.  
  32. (define (res-input r)
  33.   (cdr r))
  34.  
  35. ;;
  36.  
  37. (define (token? e)
  38.   (and (list? e)
  39.        (> (length e) 0)
  40.        (eq? (car e) 'token)))
  41.  
  42. (define (token-args e)
  43.   (cdr e))
  44.  
  45. (define (nt? e)
  46.   (symbol? e))
  47.  
  48. ;;
  49.  
  50. (define (parse g e i)
  51.   (cond [(token? e) (match-token (token-args e) i)]
  52.         [(nt? e) (parse-nt g (lookup-def g e) i)]))
  53.  
  54. (define (parse-nt g ps i)
  55.   (if (null? ps)
  56.       parse-error
  57.       (let ([r (parse-many g (rule-body (car ps)) i)])
  58.         (if (parse-error? r)
  59.             (parse-nt g (cdr ps) i)
  60.             (res (cons (rule-name (car ps)) (res-val r))
  61.                  (res-input r))))))
  62.  
  63. (define (parse-many g es i)
  64.   (if (null? es)
  65.       (res null i)
  66.       (let ([r (parse g (car es) i)])
  67.         (if (parse-error? r)
  68.             parse-error
  69.             (let ([rs (parse-many g (cdr es) (res-input r))])
  70.               (if (parse-error? rs)
  71.                   parse-error
  72.                   (res (cons (res-val r) (res-val rs))
  73.                        (res-input rs))))))))
  74.  
  75. (define (match-token xs i)
  76.   (if (and (not (null? i))
  77.            (member (car i) xs))
  78.       (res (car i) (cdr i))
  79.       parse-error))
  80.  
  81. ;;
  82.  
  83. (define num-grammar
  84.   '([digit {DIG (token #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9)}]
  85.     [numb {MANY digit numb}
  86.           {SINGLE digit}]))
  87.  
  88. (define (node-name t)
  89.   (car t))
  90.  
  91. (define (c->int c)
  92.   (- (char->integer c) (char->integer #\0)))
  93.  
  94. (define (walk-tree-acc t acc)
  95.   (cond [(eq? (node-name t) 'MANY)
  96.          (walk-tree-acc
  97.           (third t)
  98.           (+ (* 10 acc) (c->int (second (second t)))))]
  99.         [(eq? (node-name t) 'SINGLE)
  100.          (+ (* 10 acc) (c->int (second (second t))))]))
  101.  
  102. (define (walk-tree t)
  103.   (walk-tree-acc t 0))
  104.  
  105. (define arith-grammar
  106.   (append num-grammar
  107.      '([add-expr  {ADD-MANY   sub-expr (token #\+) add-expr}
  108.                   {ADD-SINGLE sub-expr}]
  109.        [sub-expr  {SUB-MANY mult-expr (token #\-) sub-expr}
  110.                   {SUB-SINGLE mult-expr}]
  111.        [mult-expr {MULT-MANY div-expr (token #\*) mult-expr}
  112.                   {MULT-SINGLE div-expr}]
  113.        [div-expr  {DIV-MANY base-expr (token #\/) div-expr}
  114.                   {DIV-SINGLE base-expr}]
  115.        [base-expr {BASE-NUM numb}
  116.                   {PARENS (token #\() add-expr (token #\))}])))
  117.  
  118. (define (arith-walk-tree t)
  119.   (cond [(eq? (node-name t) 'ADD-SINGLE)
  120.          (arith-walk-tree (second t))]
  121.         [(eq? (node-name t) 'SUB-SINGLE)
  122.          (arith-walk-tree (second t))]
  123.         [(eq? (node-name t) 'MULT-SINGLE)
  124.          (arith-walk-tree (second t))]
  125.         [(eq? (node-name t) 'DIV-SINGLE)
  126.          (arith-walk-tree (second t))]
  127.         [(eq? (node-name t) 'ADD-MANY)
  128.          (binop-cons
  129.           '+
  130.           (arith-walk-tree (second t))
  131.           (arith-walk-tree (fourth t)))]
  132.         [(eq? (node-name t) 'SUB-MANY)
  133.          (if (eq? (node-name (fourth t)) `SUB-MANY)
  134.              (binop-cons
  135.               '-
  136.               (binop-cons
  137.                '-
  138.                (arith-walk-tree (second t))
  139.                (arith-walk-tree (second (fourth t))))
  140.               (arith-walk-tree  (fourth (fourth t))))
  141.          (binop-cons
  142.           '-
  143.           (arith-walk-tree (second t))
  144.           (arith-walk-tree (fourth t))))]
  145.         [(eq? (node-name t) 'MULT-MANY)
  146.          (binop-cons
  147.           '*
  148.           (arith-walk-tree (second t))
  149.           (arith-walk-tree (fourth t)))]
  150.         [(eq? (node-name t) 'DIV-MANY)
  151.          (binop-cons
  152.           '/
  153.           (arith-walk-tree (second t))
  154.           (arith-walk-tree (fourth t)))]
  155.         [(eq? (node-name t) 'BASE-NUM)
  156.          (walk-tree (second t))]
  157.         [(eq? (node-name t) 'PARENS)
  158.          (arith-walk-tree (third t))]))
  159.  
  160. (define (calc s)
  161.  (eval
  162.   (arith-walk-tree
  163.    (car
  164.     (parse
  165.        arith-grammar
  166.        'add-expr
  167.        (string->list s))))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement