Dana Vrajitoru
C311 Programming Languages

Parser Implementation

LL(1) Table-Based Parsing

Example

Table Parsing

Table for the Expression
+ - * / ( ) id nr else
E 1 1 1 1 1 1 1 1 -
TT 2 2 3 3 3 3 3 3 -
T 4 4 4 4 4 4 4 4 -
FT 6 6 5 5 6 6 6 6 -
F - - - - 7 - 8 9 -
AO 10 11 - - - - - - -
MO - - 12 13 - - - - -

Stack-based Parsing

Recursive Descent

Implementation

; input is a global variable
(defun move-input ()
  (pop input)  t)

; factor => ( expr ) | id | number
(defun check-factor ()
  (cond ((symbolp (car input)) 
         (pop input) t)
        ((numberp (car input)) 
         (pop input) t)
        ((equal (car input) "(")
         (move-input)
         (and (check-expr)
              (equal (car input) ")")
              (move-input)))
        (t nil)))

Building the Tree

(defun parse-factor ()
  (let ((token (car input)) (Exp nil))
    (cond ((or (symbolp token) 
               (numberp token))
           (move-input)
           (list 'factor token))
          ((equal token "(")
           (move-input)
           (if (and (setq Expr (parse-expr))
                (equal (car input) ")")
                (move-input)))
           (list 'factor "(" Expr ")"))
          (t nil))))

Example
Partial lisp parsing of the grammar interpreting an arithmetic expression.

Evaluate the Parse Tree

Example

(defun eval-tree (Tree)
  (let ((root (car Tree)))
    (cond
     ((equal root 'factor)
      (if (= (length Tree) 2) 
          ; number or symbol
          (eval (cadr Tree))
        (eval-tree (caddr Tree)))))))

Separate Functions

; '(factor 2)
; '(factor a)
; '(factor "(" (E ...) ")")
(defun eval1-factor (Tree Prev)
  (if (or (not Tree)
          (not (equal root 'factor)))
      nil
    (if (= (length Tree) 2) ; number or symbol
        (eval (cadr Tree))
      (eval1-E (elt Tree 2)))))

Direct Evaluation
When all the operands involved in an operation are direct children of the root, as well as the terminal identifying the operation, the function can simply evaluate all the children, then return the operation applied to the results.

E => T AO TT
(eval-E) means:
(setq r1 (eval-T))
(setq r2 (eval-TT))
(+ r1 r2)

; E => T
; E => T AO TT
; TT => T
; TT => T AO TT
; '(E (T ...))
; '(E (T ...) "+" (TT ...))
(defun eval-E (Tree)
  (if (equal (length Tree) 1)
      (eval-T (cadr Tree))
    (let ((r1 (eval-T (cadr Tree)) )
          (r2 (eval-TT (elt Tree 3))))
      (cond ((equal (elt Tree 2) "+")
             (+ r1 r2))
            ((equal (elt Tree 2) "-")
             (- r1 r2))
            (t nil)))))

More Evaluation

Example
Complete Elisp implementation for the simple grammar recognizing strings like (1 + 1 ).

Evaluating an expression
Parameter passed forward
Lambda expression returned