LL(1) Table-Based Parsing
Example
| ( | ) | 1 | + | else | |
| S | 2 | - | 1 | - | - |
| F | - | - | 3 | - | - |
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
E =>T TT TT => AO T TT (E (T ...) (TT (A +) (T...) (TT...)))
Example
Complete Elisp implementation for the
simple grammar recognizing strings like (1 + 1 ).
Evaluating an expression
Parameter passed forward
Lambda expression returned