***     COCS3308        EXAMPLE-PROGRAM-4       10/22/2002
***	EXAMPLE PROGRAM TO GENERATE LISTS OF A GIVEN LENGTH
***	ACCORDING TO THE FOLLOWING PRODUCTION RULES
***	1. S---> a
***	2. S---> ()
***	3. S---> (R)
***	4. R---> S
***     5. R---> R S
*************************************************
	&anchor = 0
***     &ftrace = 20
        define('print(list)')
	define('nextgen(list,nont,term)')
	define('ss(list,nont,term)save')
	define('rr(list,nont,term)save')
*************************************************
***	Main program starts here
*************************************************
        rs = any('RS')  . rors
        r  = 'R'       
        s  = 'S'       
	leng = 0
        maxl = 8
loop    leng = lt(leng,maxl) leng + 1                           :f(end)
        output = 
        output = 'LIST LENGTH:::' leng
	count = 0
	list = 'S'
	ss(list,1,0)						:(loop)
***********************************************
print   count = count + 1
        expression = replace( list, 'RS', 'aa')
        output = eq(count,1) "TESTING CONTENTS OF LIST:::" List
        output = LT(COUNT,10)  '   ' count ':::  '  expression   :S(return)
        OUTPUT = LT(COUNT,100)  '  ' COUNT ":::  "  EXPRESSION   :S(RETURN)
        OUTPUT =                 " " COUNT ":::  "  EXPRESSION   :(RETURN)
***********************************************
nextgen eq(nont + term, leng) print(list, count)                :s(return)
        output = GT(nont + term, leng)
+                "ERROR: TOO MANY SYMBOLS GENERATED:"           :S(FRETURN)
        list rs                                                
        ident(rors, 'S') ss(list, nont, term)                   :s(return)
        ident(rors, 'R') rr(list, nont, term)                   :S(return)
        output = "ERROR: NEITHER NONTERMINAL PRESENT:"          :(FRETURN)
***********************************************
ss      eq(nont + term, leng) print(list, count)                :s(return)
        save = list             ;* save is local
	output = gt(nont + term, leng)
+                'ERROR: TOO MANY SYMBOLS ALREADY GENERATED:'   :s(freturn)
***
rule1   ;*  S -> a
        le(nont, 1) lt(nont + term, leng)                       :s(rule2)
        list s = 'a'                                          
	nextgen(list, nont - 1, term + 1)
***********************************************
rule2   ;*  S -> ()
        list = save
	le(nont, 1) lt(nont + term + 1, leng)			:s(rule3)
        list s = '()'                                         
	nextgen(list, nont - 1, term + 2)
**********************************************
rule3	list = save
        list s = le(nont + term + 2, leng) '(R)'                :f(return)
        rr(list, nont, term + 2)                                :(return)
**********************************************
rr      eq(nont + term, leng) print(list)                       :S(RETURN)
        save = list
rule4	list r = 'S'						:f(rule5)
	ss(list, nont, term)
**********************************************
rule5	list = save
        list r = le(nont + term + 1, leng) 'RS'                 :f(return)
        rr(list, nont + 1, term)                                :(return)
end