| 46845 |      1 | (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)
 | 
|  |      2 | 
 | 
|  |      3 | (* drt (12/15/89) -- the functor should be used during development work,
 | 
|  |      4 |    but it is wastes space in the release version.
 | 
|  |      5 |    
 | 
|  |      6 | functor ParserGen(structure LrTable : LR_TABLE
 | 
|  |      7 | 		  structure Stream : STREAM) : LR_PARSER =
 | 
|  |      8 | *)
 | 
|  |      9 | 
 | 
|  |     10 | structure LrParser :> LR_PARSER =
 | 
|  |     11 |  struct
 | 
|  |     12 |      val print = fn s => output(std_out,s)
 | 
|  |     13 |      val println = fn s => (print s; print "\n")
 | 
|  |     14 |      structure LrTable = LrTable
 | 
|  |     15 |      structure Stream = Stream
 | 
|  |     16 |      structure Token : TOKEN =
 | 
|  |     17 | 	struct
 | 
|  |     18 | 	    structure LrTable = LrTable
 | 
|  |     19 | 	    datatype ('a,'b) token = TOKEN of LrTable.term * ('a * 'b * 'b)
 | 
|  |     20 | 	    val sameToken = fn (TOKEN (t,_),TOKEN(t',_)) => t=t'
 | 
|  |     21 | 	end
 | 
|  |     22 |      
 | 
|  |     23 | 
 | 
|  |     24 |      open LrTable 
 | 
|  |     25 |      open Token
 | 
|  |     26 | 
 | 
|  |     27 |      val DEBUG = false
 | 
|  |     28 |      exception ParseError
 | 
|  |     29 | 
 | 
|  |     30 |       type ('a,'b) elem = (state * ('a * 'b * 'b))
 | 
|  |     31 |       type ('a,'b) stack = ('a,'b) elem list
 | 
|  |     32 | 
 | 
|  |     33 |       val showState = fn (STATE s) => ("STATE " ^ (makestring s))
 | 
|  |     34 | 
 | 
|  |     35 |       fun printStack(stack: ('a,'b) elem list, n: int) =
 | 
|  |     36 |          case stack
 | 
|  |     37 |            of (state, _) :: rest =>
 | 
|  |     38 |                  (print("          " ^ makestring n ^ ": ");
 | 
|  |     39 |                   println(showState state);
 | 
|  |     40 |                   printStack(rest, n+1)
 | 
|  |     41 |                  )
 | 
|  |     42 |             | nil => ()
 | 
|  |     43 | 
 | 
|  |     44 |       val parse = fn {arg : 'a,
 | 
|  |     45 | 		      table : LrTable.table,
 | 
|  |     46 | 		      lexer : ('_b,'_c) token Stream.stream,
 | 
|  |     47 | 		      saction : int * '_c * ('_b,'_c) stack * 'a ->
 | 
|  |     48 | 				nonterm * ('_b * '_c * '_c) * ('_b,'_c) stack,
 | 
|  |     49 | 		      void : '_b,
 | 
|  |     50 | 		      ec = {is_keyword,preferred_change,
 | 
|  |     51 | 			    errtermvalue,showTerminal,
 | 
|  |     52 | 			    error,terms,noShift},
 | 
|  |     53 | 		      lookahead} =>
 | 
|  |     54 |  let fun prAction(stack as (state, _) :: _, 
 | 
|  |     55 | 		  next as (TOKEN (term,_),_), action) =
 | 
|  |     56 |              (println "Parse: state stack:";
 | 
|  |     57 |               printStack(stack, 0);
 | 
|  |     58 |               print("       state="
 | 
|  |     59 |                          ^ showState state	
 | 
|  |     60 |                          ^ " next="
 | 
|  |     61 |                          ^ showTerminal term
 | 
|  |     62 |                          ^ " action="
 | 
|  |     63 |                         );
 | 
|  |     64 |               case action
 | 
|  |     65 |                 of SHIFT s => println ("SHIFT " ^ showState s)
 | 
|  |     66 |                  | REDUCE i => println ("REDUCE " ^ (makestring i))
 | 
|  |     67 |                  | ERROR => println "ERROR"
 | 
|  |     68 | 		 | ACCEPT => println "ACCEPT";
 | 
|  |     69 |               action)
 | 
|  |     70 |         | prAction (_,_,action) = action
 | 
|  |     71 | 
 | 
|  |     72 |       val action = LrTable.action table
 | 
|  |     73 |       val goto = LrTable.goto table
 | 
|  |     74 | 
 | 
|  |     75 |       fun parseStep(next as (TOKEN (terminal, value as (_,leftPos,_)),lexer) :
 | 
|  |     76 | 			('_b,'_c) token * ('_b,'_c) token Stream.stream,
 | 
|  |     77 | 		    stack as (state,_) :: _ : ('_b ,'_c) stack) =
 | 
|  |     78 |          case (if DEBUG then prAction(stack, next,action(state, terminal))
 | 
|  |     79 |                else action(state, terminal))
 | 
|  |     80 |               of SHIFT s => parseStep(Stream.get lexer, (s,value) :: stack)
 | 
|  |     81 |                | REDUCE i =>
 | 
|  |     82 | 		    let val (nonterm,value,stack as (state,_) :: _ ) =
 | 
|  |     83 | 					 saction(i,leftPos,stack,arg)
 | 
|  |     84 | 		    in parseStep(next,(goto(state,nonterm),value)::stack)
 | 
|  |     85 | 		    end
 | 
|  |     86 |                | ERROR => let val (_,leftPos,rightPos) = value
 | 
|  |     87 | 		          in error("syntax error\n",leftPos,rightPos);
 | 
|  |     88 | 			     raise ParseError
 | 
|  |     89 | 			  end
 | 
|  |     90 |   	       | ACCEPT => let val (_,(topvalue,_,_)) :: _ = stack
 | 
|  |     91 | 			       val (token,restLexer) = next
 | 
|  |     92 | 			   in (topvalue,Stream.cons(token,lexer))
 | 
|  |     93 | 			   end
 | 
|  |     94 |       val next as (TOKEN (terminal,(_,leftPos,_)),_) = Stream.get lexer
 | 
|  |     95 |    in parseStep(next,[(initialState table,(void,leftPos,leftPos))])
 | 
|  |     96 |    end
 | 
|  |     97 | end;
 | 
|  |     98 | 
 |