src/HOL/TPTP/TPTP_Parser/ml-yacc/lib/parser2.sml
author wenzelm
Wed, 04 Oct 2017 12:00:53 +0200
changeset 66787 64b47495676d
parent 46845 6431a93ffeb6
permissions -rw-r--r--
obsolete;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
46845
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
     1
(* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
     2
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
     3
(* parser.sml:  This is a parser driver for LR tables with an error-recovery
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
     4
   routine added to it.  The routine used is described in detail in this
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
     5
   article:
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
     6
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
     7
	'A Practical Method for LR and LL Syntactic Error Diagnosis and
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
     8
	 Recovery', by M. Burke and G. Fisher, ACM Transactions on
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
     9
	 Programming Langauges and Systems, Vol. 9, No. 2, April 1987,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    10
	 pp. 164-197.
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    11
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    12
    This program is an implementation is the partial, deferred method discussed
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    13
    in the article.  The algorithm and data structures used in the program
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    14
    are described below.  
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    15
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    16
    This program assumes that all semantic actions are delayed.  A semantic
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    17
    action should produce a function from unit -> value instead of producing the
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    18
    normal value.  The parser returns the semantic value on the top of the
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    19
    stack when accept is encountered.  The user can deconstruct this value
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    20
    and apply the unit -> value function in it to get the answer.
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    21
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    22
    It also assumes that the lexer is a lazy stream.
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    23
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    24
    Data Structures:
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    25
    ----------------
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    26
	
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    27
	* The parser:
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    28
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    29
	   The state stack has the type
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    30
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    31
		 (state * (semantic value * line # * line #)) list
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    32
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    33
	   The parser keeps a queue of (state stack * lexer pair).  A lexer pair
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    34
	 consists of a terminal * value pair and a lexer.  This allows the 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    35
	 parser to reconstruct the states for terminals to the left of a
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    36
	 syntax error, and attempt to make error corrections there.
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    37
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    38
	   The queue consists of a pair of lists (x,y).  New additions to
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    39
	 the queue are cons'ed onto y.  The first element of x is the top
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    40
	 of the queue.  If x is nil, then y is reversed and used
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    41
	 in place of x.
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    42
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    43
    Algorithm:
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    44
    ----------
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    45
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    46
	* The steady-state parser:  
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    47
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    48
	    This parser keeps the length of the queue of state stacks at
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    49
	a steady state by always removing an element from the front when
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    50
	another element is placed on the end.
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    51
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    52
	    It has these arguments:
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    53
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    54
	   stack: current stack
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    55
	   queue: value of the queue
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    56
	   lexPair ((terminal,value),lex stream)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    57
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    58
	When SHIFT is encountered, the state to shift to and the value are
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    59
	are pushed onto the state stack.  The state stack and lexPair are
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    60
	placed on the queue.  The front element of the queue is removed.
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    61
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    62
	When REDUCTION is encountered, the rule is applied to the current
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    63
	stack to yield a triple (nonterm,value,new stack).  A new
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    64
	stack is formed by adding (goto(top state of stack,nonterm),value)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    65
	to the stack.
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    66
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    67
	When ACCEPT is encountered, the top value from the stack and the
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    68
	lexer are returned.
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    69
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    70
	When an ERROR is encountered, fixError is called.  FixError
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    71
	takes the arguments to the parser, fixes the error if possible and
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    72
        returns a new set of arguments.
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    73
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    74
	* The distance-parser:
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    75
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    76
	This parser includes an additional argument distance.  It pushes
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    77
	elements on the queue until it has parsed distance tokens, or an
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    78
	ACCEPT or ERROR occurs.  It returns a stack, lexer, the number of
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    79
	tokens left unparsed, a queue, and an action option.
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    80
*)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    81
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    82
signature FIFO = 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    83
  sig type 'a queue
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    84
      val empty : 'a queue
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    85
      exception Empty
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    86
      val get : 'a queue -> 'a * 'a queue
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    87
      val put : 'a * 'a queue -> 'a queue
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    88
  end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    89
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    90
(* drt (12/15/89) -- the functor should be used in development work, but
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    91
   it wastes space in the release version.
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    92
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    93
functor ParserGen(structure LrTable : LR_TABLE
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    94
		  structure Stream : STREAM) : LR_PARSER =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    95
*)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    96
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    97
structure LrParser :> LR_PARSER =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    98
   struct
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
    99
      structure LrTable = LrTable
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   100
      structure Stream = Stream
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   101
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   102
      fun eqT (LrTable.T i, LrTable.T i') = i = i'
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   103
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   104
      structure Token : TOKEN =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   105
	struct
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   106
	    structure LrTable = LrTable
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   107
	    datatype ('a,'b) token = TOKEN of LrTable.term * ('a * 'b * 'b)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   108
	    val sameToken = fn (TOKEN(t,_),TOKEN(t',_)) => eqT (t,t')
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   109
        end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   110
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   111
      open LrTable
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   112
      open Token
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   113
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   114
      val DEBUG1 = false
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   115
      val DEBUG2 = false
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   116
      exception ParseError
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   117
      exception ParseImpossible of int
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   118
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   119
      structure Fifo :> FIFO =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   120
        struct
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   121
	  type 'a queue = ('a list * 'a list)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   122
	  val empty = (nil,nil)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   123
	  exception Empty
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   124
	  fun get(a::x, y) = (a, (x,y))
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   125
	    | get(nil, nil) = raise Empty
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   126
	    | get(nil, y) = get(rev y, nil)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   127
 	  fun put(a,(x,y)) = (x,a::y)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   128
        end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   129
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   130
      type ('a,'b) elem = (state * ('a * 'b * 'b))
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   131
      type ('a,'b) stack = ('a,'b) elem list
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   132
      type ('a,'b) lexv = ('a,'b) token
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   133
      type ('a,'b) lexpair = ('a,'b) lexv * (('a,'b) lexv Stream.stream)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   134
      type ('a,'b) distanceParse =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   135
		 ('a,'b) lexpair *
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   136
		 ('a,'b) stack * 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   137
		 (('a,'b) stack * ('a,'b) lexpair) Fifo.queue *
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   138
		 int ->
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   139
		   ('a,'b) lexpair *
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   140
		   ('a,'b) stack * 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   141
		   (('a,'b) stack * ('a,'b) lexpair) Fifo.queue *
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   142
		   int *
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   143
		   action option
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   144
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   145
      type ('a,'b) ecRecord =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   146
	 {is_keyword : term -> bool,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   147
          preferred_change : (term list * term list) list,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   148
	  error : string * 'b * 'b -> unit,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   149
	  errtermvalue : term -> 'a,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   150
	  terms : term list,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   151
	  showTerminal : term -> string,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   152
	  noShift : term -> bool}
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   153
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   154
      local 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   155
	 val print = fn s => TextIO.output(TextIO.stdOut,s)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   156
	 val println = fn s => (print s; print "\n")
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   157
	 val showState = fn (STATE s) => "STATE " ^ (Int.toString s)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   158
      in
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   159
        fun printStack(stack: ('a,'b) stack, n: int) =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   160
         case stack
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   161
           of (state,_) :: rest =>
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   162
                 (print("\t" ^ Int.toString n ^ ": ");
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   163
                  println(showState state);
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   164
                  printStack(rest, n+1))
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   165
            | nil => ()
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   166
                
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   167
        fun prAction showTerminal
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   168
		 (stack as (state,_) :: _, next as (TOKEN (term,_),_), action) =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   169
             (println "Parse: state stack:";
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   170
              printStack(stack, 0);
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   171
              print("       state="
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   172
                         ^ showState state	
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   173
                         ^ " next="
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   174
                         ^ showTerminal term
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   175
                         ^ " action="
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   176
                        );
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   177
              case action
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   178
                of SHIFT state => println ("SHIFT " ^ (showState state))
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   179
                 | REDUCE i => println ("REDUCE " ^ (Int.toString i))
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   180
                 | ERROR => println "ERROR"
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   181
		 | ACCEPT => println "ACCEPT")
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   182
        | prAction _ (_,_,action) = ()
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   183
     end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   184
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   185
    (* ssParse: parser which maintains the queue of (state * lexvalues) in a
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   186
	steady-state.  It takes a table, showTerminal function, saction
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   187
	function, and fixError function.  It parses until an ACCEPT is
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   188
	encountered, or an exception is raised.  When an error is encountered,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   189
	fixError is called with the arguments of parseStep (lexv,stack,and
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   190
	queue).  It returns the lexv, and a new stack and queue adjusted so
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   191
	that the lexv can be parsed *)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   192
	
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   193
    val ssParse =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   194
      fn (table,showTerminal,saction,fixError,arg) =>
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   195
	let val prAction = prAction showTerminal
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   196
	    val action = LrTable.action table
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   197
	    val goto = LrTable.goto table
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   198
	    fun parseStep(args as
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   199
			 (lexPair as (TOKEN (terminal, value as (_,leftPos,_)),
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   200
				      lexer
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   201
				      ),
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   202
			  stack as (state,_) :: _,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   203
			  queue)) =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   204
	      let val nextAction = action (state,terminal)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   205
	          val _ = if DEBUG1 then prAction(stack,lexPair,nextAction)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   206
			  else ()
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   207
	      in case nextAction
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   208
		 of SHIFT s =>
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   209
		  let val newStack = (s,value) :: stack
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   210
		      val newLexPair = Stream.get lexer
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   211
		      val (_,newQueue) =Fifo.get(Fifo.put((newStack,newLexPair),
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   212
							    queue))
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   213
		  in parseStep(newLexPair,(s,value)::stack,newQueue)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   214
		  end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   215
		 | REDUCE i =>
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   216
		     (case saction(i,leftPos,stack,arg)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   217
		      of (nonterm,value,stack as (state,_) :: _) =>
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   218
		          parseStep(lexPair,(goto(state,nonterm),value)::stack,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   219
				    queue)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   220
		       | _ => raise (ParseImpossible 197))
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   221
		 | ERROR => parseStep(fixError args)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   222
		 | ACCEPT => 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   223
			(case stack
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   224
			 of (_,(topvalue,_,_)) :: _ =>
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   225
				let val (token,restLexer) = lexPair
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   226
				in (topvalue,Stream.cons(token,restLexer))
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   227
				end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   228
			  | _ => raise (ParseImpossible 202))
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   229
	      end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   230
	    | parseStep _ = raise (ParseImpossible 204)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   231
	in parseStep
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   232
	end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   233
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   234
    (*  distanceParse: parse until n tokens are shifted, or accept or
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   235
	error are encountered.  Takes a table, showTerminal function, and
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   236
	semantic action function.  Returns a parser which takes a lexPair
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   237
	(lex result * lexer), a state stack, a queue, and a distance
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   238
	(must be > 0) to parse.  The parser returns a new lex-value, a stack
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   239
	with the nth token shifted on top, a queue, a distance, and action
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   240
	option. *)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   241
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   242
    val distanceParse =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   243
      fn (table,showTerminal,saction,arg) =>
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   244
	let val prAction = prAction showTerminal
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   245
	    val action = LrTable.action table
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   246
	    val goto = LrTable.goto table
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   247
	    fun parseStep(lexPair,stack,queue,0) = (lexPair,stack,queue,0,NONE)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   248
	      | parseStep(lexPair as (TOKEN (terminal, value as (_,leftPos,_)),
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   249
				      lexer
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   250
				     ),
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   251
			  stack as (state,_) :: _,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   252
			  queue,distance) =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   253
	      let val nextAction = action(state,terminal)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   254
	          val _ = if DEBUG1 then prAction(stack,lexPair,nextAction)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   255
			  else ()
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   256
	      in case nextAction
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   257
		 of SHIFT s =>
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   258
		  let val newStack = (s,value) :: stack
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   259
		      val newLexPair = Stream.get lexer
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   260
		  in parseStep(newLexPair,(s,value)::stack,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   261
			       Fifo.put((newStack,newLexPair),queue),distance-1)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   262
		  end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   263
		 | REDUCE i =>
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   264
		    (case saction(i,leftPos,stack,arg)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   265
		      of (nonterm,value,stack as (state,_) :: _) =>
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   266
		         parseStep(lexPair,(goto(state,nonterm),value)::stack,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   267
				 queue,distance)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   268
		      | _ => raise (ParseImpossible 240))
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   269
		 | ERROR => (lexPair,stack,queue,distance,SOME nextAction)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   270
		 | ACCEPT => (lexPair,stack,queue,distance,SOME nextAction)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   271
	      end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   272
	   | parseStep _ = raise (ParseImpossible 242)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   273
	in parseStep : ('_a,'_b) distanceParse 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   274
	end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   275
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   276
(* mkFixError: function to create fixError function which adjusts parser state
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   277
   so that parse may continue in the presence of an error *)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   278
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   279
fun mkFixError({is_keyword,terms,errtermvalue,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   280
	      preferred_change,noShift,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   281
	      showTerminal,error,...} : ('_a,'_b) ecRecord,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   282
	     distanceParse : ('_a,'_b) distanceParse,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   283
	     minAdvance,maxAdvance) 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   284
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   285
            (lexv as (TOKEN (term,value as (_,leftPos,_)),_),stack,queue) =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   286
    let val _ = if DEBUG2 then
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   287
			error("syntax error found at " ^ (showTerminal term),
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   288
			      leftPos,leftPos)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   289
		else ()
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   290
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   291
        fun tokAt(t,p) = TOKEN(t,(errtermvalue t,p,p))
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   292
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   293
	val minDelta = 3
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   294
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   295
	(* pull all the state * lexv elements from the queue *)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   296
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   297
	val stateList = 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   298
	   let fun f q = let val (elem,newQueue) = Fifo.get q
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   299
			 in elem :: (f newQueue)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   300
			 end handle Fifo.Empty => nil
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   301
	   in f queue
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   302
	   end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   303
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   304
	(* now number elements of stateList, giving distance from
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   305
	   error token *)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   306
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   307
	val (_, numStateList) =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   308
	      List.foldr (fn (a,(num,r)) => (num+1,(a,num)::r)) (0, []) stateList
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   309
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   310
	(* Represent the set of potential changes as a linked list.
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   311
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   312
	   Values of datatype Change hold information about a potential change.
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   313
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   314
	   oper = oper to be applied
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   315
	   pos = the # of the element in stateList that would be altered.
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   316
	   distance = the number of tokens beyond the error token which the
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   317
	     change allows us to parse.
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   318
	   new = new terminal * value pair at that point
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   319
	   orig = original terminal * value pair at the point being changed.
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   320
	 *)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   321
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   322
	datatype ('a,'b) change = CHANGE of
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   323
	   {pos : int, distance : int, leftPos: 'b, rightPos: 'b,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   324
	    new : ('a,'b) lexv list, orig : ('a,'b) lexv list}
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   325
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   326
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   327
         val showTerms = concat o map (fn TOKEN(t,_) => " " ^ showTerminal t)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   328
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   329
	 val printChange = fn c =>
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   330
	  let val CHANGE {distance,new,orig,pos,...} = c
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   331
	  in (print ("{distance= " ^ (Int.toString distance));
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   332
	      print (",orig ="); print(showTerms orig);
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   333
	      print (",new ="); print(showTerms new);
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   334
	      print (",pos= " ^ (Int.toString pos));
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   335
	      print "}\n")
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   336
	  end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   337
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   338
	val printChangeList = app printChange
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   339
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   340
(* parse: given a lexPair, a stack, and the distance from the error
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   341
   token, return the distance past the error token that we are able to parse.*)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   342
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   343
	fun parse (lexPair,stack,queuePos : int) =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   344
	    case distanceParse(lexPair,stack,Fifo.empty,queuePos+maxAdvance+1)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   345
             of (_,_,_,distance,SOME ACCEPT) => 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   346
		        if maxAdvance-distance-1 >= 0 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   347
			    then maxAdvance 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   348
			    else maxAdvance-distance-1
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   349
	      | (_,_,_,distance,_) => maxAdvance - distance - 1
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   350
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   351
(* catList: concatenate results of scanning list *)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   352
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   353
	fun catList l f = List.foldr (fn(a,r)=> f a @ r) [] l
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   354
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   355
        fun keywordsDelta new = if List.exists (fn(TOKEN(t,_))=>is_keyword t) new
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   356
	               then minDelta else 0
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   357
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   358
        fun tryChange{lex,stack,pos,leftPos,rightPos,orig,new} =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   359
	     let val lex' = List.foldr (fn (t',p)=>(t',Stream.cons p)) lex new
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   360
		 val distance = parse(lex',stack,pos+length new-length orig)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   361
	      in if distance >= minAdvance + keywordsDelta new 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   362
		   then [CHANGE{pos=pos,leftPos=leftPos,rightPos=rightPos,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   363
				distance=distance,orig=orig,new=new}] 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   364
		   else []
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   365
	     end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   366
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   367
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   368
(* tryDelete: Try to delete n terminals.
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   369
              Return single-element [success] or nil.
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   370
	      Do not delete unshiftable terminals. *)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   371
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   372
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   373
    fun tryDelete n ((stack,lexPair as (TOKEN(term,(_,l,r)),_)),qPos) =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   374
	let fun del(0,accum,left,right,lexPair) =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   375
	          tryChange{lex=lexPair,stack=stack,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   376
			    pos=qPos,leftPos=left,rightPos=right,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   377
			    orig=rev accum, new=[]}
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   378
	      | del(n,accum,left,right,(tok as TOKEN(term,(_,_,r)),lexer)) =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   379
		   if noShift term then []
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   380
		   else del(n-1,tok::accum,left,r,Stream.get lexer)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   381
         in del(n,[],l,r,lexPair)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   382
        end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   383
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   384
(* tryInsert: try to insert tokens before the current terminal;
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   385
       return a list of the successes  *)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   386
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   387
        fun tryInsert((stack,lexPair as (TOKEN(_,(_,l,_)),_)),queuePos) =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   388
	       catList terms (fn t =>
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   389
		 tryChange{lex=lexPair,stack=stack,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   390
			   pos=queuePos,orig=[],new=[tokAt(t,l)],
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   391
			   leftPos=l,rightPos=l})
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   392
			      
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   393
(* trySubst: try to substitute tokens for the current terminal;
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   394
       return a list of the successes  *)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   395
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   396
        fun trySubst ((stack,lexPair as (orig as TOKEN (term,(_,l,r)),lexer)),
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   397
		      queuePos) =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   398
	      if noShift term then []
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   399
	      else
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   400
		  catList terms (fn t =>
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   401
		      tryChange{lex=Stream.get lexer,stack=stack,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   402
				pos=queuePos,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   403
				leftPos=l,rightPos=r,orig=[orig],
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   404
				new=[tokAt(t,r)]})
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   405
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   406
     (* do_delete(toks,lexPair) tries to delete tokens "toks" from "lexPair".
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   407
         If it succeeds, returns SOME(toks',l,r,lp), where
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   408
	     toks' is the actual tokens (with positions and values) deleted,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   409
	     (l,r) are the (leftmost,rightmost) position of toks', 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   410
	     lp is what remains of the stream after deletion 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   411
     *)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   412
        fun do_delete(nil,lp as (TOKEN(_,(_,l,_)),_)) = SOME(nil,l,l,lp)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   413
          | do_delete([t],(tok as TOKEN(t',(_,l,r)),lp')) =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   414
	       if eqT (t, t')
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   415
		   then SOME([tok],l,r,Stream.get lp')
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   416
                   else NONE
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   417
          | do_delete(t::rest,(tok as TOKEN(t',(_,l,r)),lp')) =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   418
	       if eqT (t,t')
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   419
		   then case do_delete(rest,Stream.get lp')
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   420
                         of SOME(deleted,l',r',lp'') =>
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   421
			       SOME(tok::deleted,l,r',lp'')
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   422
			  | NONE => NONE
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   423
		   else NONE
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   424
			     
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   425
        fun tryPreferred((stack,lexPair),queuePos) =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   426
	    catList preferred_change (fn (delete,insert) =>
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   427
	       if List.exists noShift delete then [] (* should give warning at
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   428
						 parser-generation time *)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   429
               else case do_delete(delete,lexPair)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   430
                     of SOME(deleted,l,r,lp) => 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   431
			    tryChange{lex=lp,stack=stack,pos=queuePos,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   432
				      leftPos=l,rightPos=r,orig=deleted,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   433
				      new=map (fn t=>(tokAt(t,r))) insert}
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   434
		      | NONE => [])
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   435
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   436
	val changes = catList numStateList tryPreferred @
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   437
	                catList numStateList tryInsert @
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   438
			  catList numStateList trySubst @
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   439
			    catList numStateList (tryDelete 1) @
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   440
			      catList numStateList (tryDelete 2) @
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   441
			        catList numStateList (tryDelete 3)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   442
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   443
	val findMaxDist = fn l => 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   444
	  foldr (fn (CHANGE {distance,...},high) => Int.max(distance,high)) 0 l
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   445
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   446
(* maxDist: max distance past error taken that we could parse *)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   447
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   448
	val maxDist = findMaxDist changes
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   449
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   450
(* remove changes which did not parse maxDist tokens past the error token *)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   451
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   452
        val changes = catList changes 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   453
	      (fn(c as CHANGE{distance,...}) => 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   454
		  if distance=maxDist then [c] else [])
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   455
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   456
      in case changes 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   457
	  of (l as change :: _) =>
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   458
	      let fun print_msg (CHANGE {new,orig,leftPos,rightPos,...}) =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   459
		  let val s = 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   460
		      case (orig,new)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   461
			  of (_::_,[]) => "deleting " ^ (showTerms orig)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   462
	                   | ([],_::_) => "inserting " ^ (showTerms new)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   463
			   | _ => "replacing " ^ (showTerms orig) ^
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   464
				 " with " ^ (showTerms new)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   465
		  in error ("syntax error: " ^ s,leftPos,rightPos)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   466
		  end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   467
		   
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   468
		  val _ = 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   469
		      (if length l > 1 andalso DEBUG2 then
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   470
			   (print "multiple fixes possible; could fix it by:\n";
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   471
			    app print_msg l;
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   472
			    print "chosen correction:\n")
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   473
		       else ();
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   474
		       print_msg change)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   475
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   476
		  (* findNth: find nth queue entry from the error
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   477
		   entry.  Returns the Nth queue entry and the  portion of
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   478
		   the queue from the beginning to the nth-1 entry.  The
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   479
		   error entry is at the end of the queue.
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   480
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   481
		   Examples:
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   482
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   483
		   queue = a b c d e
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   484
		   findNth 0 = (e,a b c d)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   485
		   findNth 1 =  (d,a b c)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   486
		   *)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   487
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   488
		  val findNth = fn n =>
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   489
		      let fun f (h::t,0) = (h,rev t)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   490
			    | f (h::t,n) = f(t,n-1)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   491
			    | f (nil,_) = let exception FindNth
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   492
					  in raise FindNth
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   493
					  end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   494
		      in f (rev stateList,n)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   495
		      end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   496
		
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   497
		  val CHANGE {pos,orig,new,...} = change
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   498
		  val (last,queueFront) = findNth pos
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   499
		  val (stack,lexPair) = last
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   500
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   501
		  val lp1 = foldl(fn (_,(_,r)) => Stream.get r) lexPair orig
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   502
		  val lp2 = foldr(fn(t,r)=>(t,Stream.cons r)) lp1 new
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   503
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   504
		  val restQueue = 
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   505
		      Fifo.put((stack,lp2),
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   506
			       foldl Fifo.put Fifo.empty queueFront)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   507
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   508
		  val (lexPair,stack,queue,_,_) =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   509
		      distanceParse(lp2,stack,restQueue,pos)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   510
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   511
	      in (lexPair,stack,queue)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   512
	      end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   513
	| nil => (error("syntax error found at " ^ (showTerminal term),
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   514
			leftPos,leftPos); raise ParseError)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   515
    end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   516
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   517
   val parse = fn {arg,table,lexer,saction,void,lookahead,
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   518
		   ec=ec as {showTerminal,...} : ('_a,'_b) ecRecord} =>
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   519
	let val distance = 15   (* defer distance tokens *)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   520
	    val minAdvance = 1  (* must parse at least 1 token past error *)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   521
	    val maxAdvance = Int.max(lookahead,0)(* max distance for parse check *)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   522
	    val lexPair = Stream.get lexer
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   523
	    val (TOKEN (_,(_,leftPos,_)),_) = lexPair
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   524
	    val startStack = [(initialState table,(void,leftPos,leftPos))]
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   525
	    val startQueue = Fifo.put((startStack,lexPair),Fifo.empty)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   526
	    val distanceParse = distanceParse(table,showTerminal,saction,arg)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   527
	    val fixError = mkFixError(ec,distanceParse,minAdvance,maxAdvance)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   528
	    val ssParse = ssParse(table,showTerminal,saction,fixError,arg)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   529
	    fun loop (lexPair,stack,queue,_,SOME ACCEPT) =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   530
		   ssParse(lexPair,stack,queue)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   531
	      | loop (lexPair,stack,queue,0,_) = ssParse(lexPair,stack,queue)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   532
	      | loop (lexPair,stack,queue,distance,SOME ERROR) =
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   533
		 let val (lexPair,stack,queue) = fixError(lexPair,stack,queue)
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   534
		 in loop (distanceParse(lexPair,stack,queue,distance))
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   535
		 end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   536
	      | loop _ = let exception ParseInternal
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   537
			 in raise ParseInternal
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   538
			 end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   539
	in loop (distanceParse(lexPair,startStack,startQueue,distance))
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   540
	end
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   541
 end;
6431a93ffeb6 added ml-yacc library sources;
sultana
parents:
diff changeset
   542