Построить множество follow(1) на основе заданной ll-грамматики - Lisp
Формулировка задачи:
Есть относительно понятная реализация здесь http://inst.eecs.berkeley.edu/~cs164/software/source/firstfoll.cl
Код не запускается в силисп. Помогите пожалуйста разобраться, где его запустить и как вывести follow множество
Решение задачи: «Построить множество follow(1) на основе заданной ll-грамматики»
textual
Листинг программы
- ;; computing First and Follow sets
- ;;Here is a sample grammar
- ;; We need a way to represent a grammar in Lisp. We could do it in a
- ;; variety of different ways, for example setting up a data structure
- ;; of some kind of collection for the rules (list, hashtable, array),
- ;; some kind of indexing or selection so we can step through the
- ;; rules, some kind of constructors so we can construct the grammar
- ;; and its rules in the first place, some selectors on rule parts so
- ;; we can get the left-hand and right-hand sides, a selector so that
- ;; we can step through components in the right-hand side, etc. It
- ;; turns out that if we use lisp lists as shown below, we can make
- ;; very neat use of built-in lisp programs to manipulate
- ;; grammars... like car, cdr, mapc, list, union. Programs to print
- ;; grammars are also free; and formatted output is also pretty
- ;; standard. If we constructed a grammar data-type (and in some
- ;; languages we could mention we would have to do so), it would take
- ;; us a page of code, and all of our programs would have to use these
- ;; structures. It would make the programs relatively opaque: you
- ;; would have to be fully educated in what we had done to make sense
- ;; of them.
- ;; If this appears to you to constitute an argument against abstract
- ;; data types, you are right. It is not a mathematical, legal, or ethical
- ;; argument. In fact it is an argument based on TASTE, and reasonable
- ;; people can disagree with me about what I've done. I might even
- ;; change my mind about some of the issues, but at the moment I think
- ;; I'm right. ( :) .
- ;;
- ;; Here is what we do to define a grammar. The 2nd element in each
- ;; rule is the symbol "->". This is just for visual appearance. We
- ;; do not allow any of the extended notations like | or *. If we did,
- ;; we could write an extended-grammar to vanilla-grammar translator.
- (defparameter ; grammar 3.12
- g
- '((Z -> d)
- (Z -> X Y Z)
- (Y -> )
- (Y -> c)
- (X -> Y)
- (X -> a)))
- (defparameter lect7
- '((E -> T X)
- (T -> \( E \) )
- (T -> int Y)
- (X -> + T)
- (X -> )
- (Y -> * T)
- (Y -> )))
- ;; selecting stuff from a rule
- (defun rhs(rule)(cddr rule)) ;right hand side
- (defun lhs(rule)(car rule)) ;left hand side
- ;; Return a list of the non-terminal symbols of g by making a list of
- ;; all the symbols on the lhs. Remove duplicates from that list.
- (defun non-terminals(g) (remove-duplicates (mapcar #'lhs g)))
- ;; Return a list of the terminal symbols of the grammar g by computing
- ;; the union of all the symbols on the rhs of all the rules of g.
- ;; Eliminate the non-terminal symbols.
- (defun terminals(g)
- (set-difference (reduce #'union (mapcar #'rhs g))
- (non-terminals g) ))
- ;; a diversion to discuss MACROS.
- ;; We repeatedly need to do (setf foo (union foo z)). No big deal,
- ;; except that foo is sometimes a big expression, and we don't really
- ;; want to write it out twice. We might make a mistake and write it
- ;; differently the second time. Let's extend lisp with a macro,
- ;; addinto, so that we can write (addinto foo z). Like foo+=z in C
- ;; except we are using union instead of +. We want to take a place
- ;; and stuff and produce a new expression that looks like (setf place
- ;; (union place stuff)). But of course we must do sometime to make
- ;; place and stuff parameters.
- ;;
- ;; (defun addinto(p s)(setf p (union p s)))
- ;; -- will not work. (addinto x y) sets p to (union x y).
- ;; (defun addinto (p s) (list 'setf p (list 'union p s)))
- ;; --- will not work. (addinto x y) returns the list (setf x (union x y))
- ;; this second definition is closer, because if we
- ;; evaluate the returned list, we win. In fact
- ;; (defmacro addinto (p s) (list 'setf p (list 'union p s)))
- ;; does what we want.
- ;; The experienced lisp macro-writer is more likely to
- ;; use the "backquote" syntax, for the IDENTICAL result:
- (defmacro addinto(place stuff)
- `(setf ,place (union ,place ,stuff)))
- ;; note that backquote is just like quote except that items with a
- ;; comma in front of them are replaced by their values.
- ;; There are other tricks, including ,@ which works like this:
- ;; (setf x '(a b c))
- ;; `(x ,x) ==> (x (a b c))
- ;; `(x ,@ x) ==> (x a b c) ;,@ works by appending
- ;; Back to MACROS.
- ;; In fact, what we want to say is written in the textbook as
- ;; something like Follow[x] := Follow[x] U First[y]. where Follow might
- ;; be First or some other set associated with the symbol x.
- ;; We have chosen to represent First etc. as hashtables, which means
- ;; that to get First[X] we could write (gethash X Follow). But maybe
- ;; we will weigh in on the side of abstraction this time, and vote
- ;; against explicitly writing gethash all over. Why?
- ;; That commits us to always using the hashtable mechanism. Maybe we
- ;; will come up with another idea for the table datatype that
- ;; associates a symbol like X with several properties like First[X]
- ;; and Follow[X], and we would like to substitute our implementation
- ;; for this one, simply.
- ;; Here's a useful Macro trick, then, that abstracts out the gethash:
- ;; Like First[x] in textbook, where x is a symbol, we allow (First x)
- (defmacro First (x)
- `(gethash ,x First))
- ;; Like Follow[x] in textbook, where x is a symbol.
- (defmacro Follow(x)
- `(gethash ,x Follow))
- ;; We can now write (Follow x) instead of (gethash x Follow).
- ;; Lisp note: More significantly, using a macro allows us to write
- ;; (setf (Follow x) ...), which would not be possible if we merely
- ;; defined functions: (defun Follow(x)(gethash x Follow)).
- ;; Also, we expand this macro in the lexical environment of
- ;; the program. Thus the names First and Follow are the local
- ;; names, used in the program where the macros are used.
- ;; Combining these macros allows us to write things like
- ;;(addinto (Follow x) (First y))
- ;;; end of MACRO discussion
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д