(******************************************************************) (* GENERATED FILE -- DO NOT EDIT -- GENERATED FILE -- DO NOT EDIT *) (* GENERATED FILE -- DO NOT EDIT -- GENERATED FILE -- DO NOT EDIT *) (* GENERATED FILE -- DO NOT EDIT -- GENERATED FILE -- DO NOT EDIT *) (******************************************************************)
signature LR_TABLE = sig datatype ('a,'b) pairlist = EMPTY | PAIR of'a * 'b * ('a,'b) pairlist datatype state = STATE of int datatype term = T of int datatype nonterm = NT of int datatype action = SHIFT of state
| REDUCE of int
| ACCEPT
| ERROR type table
val numStates : table -> int val numRules : table -> int val describeActions : table -> state ->
(term,action) pairlist * action val describeGoto : table -> state -> (nonterm,state) pairlist val action : table -> state * term -> action val goto : table -> state * nonterm -> state val initialState : table -> state
exception Goto of state * nonterm
(* TOKEN: signature revealing the internal structure of a token. This signature TOKENdistinctfromthesignature{parsername}_TOKENSproducedbyML-Yacc. The{parsername}_TOKENSstructurescontainsometypesandfunctionsto constructtokensfromvaluesandpositions.
(* LEXER: a signature that most lexers produced for use with SML-Yacc's outputwillmatch.Theuserisresponsiblefordeclaringtypetoken, typepos,andtypesvalueintheUserDeclarationssectionofalexer.
signature LEXER = sig structure UserDeclarations : sig type ('a,'b) token type pos type svalue end val makeLexer : (int -> string) -> unit ->
(UserDeclarations.svalue,UserDeclarations.pos) UserDeclarations.token end
(* ARG_LEXER: the %arg option of ML-Lex allows users to produce lexers which alsotakeanargumentbeforeyieldingafunctionfromunittoatoken
*)
signature ARG_LEXER = sig structure UserDeclarations : sig type ('a,'b) token type pos type svalue type arg end val makeLexer : (int -> string) -> UserDeclarations.arg -> unit ->
(UserDeclarations.svalue,UserDeclarations.pos) UserDeclarations.token end
(* PARSER_DATA: the signature of ParserData structures in {parser name}LrValsFun producedbySML-Yacc.Allsuchstructuresmatchthissignature.
signature PARSER_DATA = sig (* the type of line numbers *)
type pos
(* the type of semantic values *)
type svalue
(* the type of the user-supplied argument to the parser *) type arg
(* the intended type of the result of the parser. This value is producedbyapplyingextractfromthestructureActionstothe finalsemanticvalueresultiingfromaparse.
*)
(* structure Actions contains the functions which mantain the semanticvaluesstackintheparser.Voidisusedtoprovide adefaultvalueforthesemanticstack.
*)
structure Actions : sig val actions : int * pos *
(LrTable.state * (svalue * pos * pos)) list * arg->
LrTable.nonterm * (svalue * pos * pos) *
((LrTable.state *(svalue * pos * pos)) list) val void : svalue val extract : svalue -> result end
(* structure EC contains information used to improve error
recovery in an error-correcting parser *)
structure EC : sig val is_keyword : LrTable.term -> bool val noShift : LrTable.term -> bool val preferred_change : (LrTable.term list * LrTable.term list) list val errtermvalue : LrTable.term -> svalue val showTerminal : LrTable.term -> string val terms: LrTable.term list end
(* table is the LR table for the parser *)
val table : LrTable.table end
(* signature PARSER is the signature that most user parsers created by SML-Yaccwillmatch.
*)
type arg type lexarg type pos type result type svalue
val makeLexer : (int -> string) -> lexarg ->
(svalue,pos) Token.token Stream.stream val parse : int * ((svalue,pos) Token.token Stream.stream) *
(string * pos * pos -> unit) * arg ->
result * (svalue,pos) Token.token Stream.stream
val sameToken : (svalue,pos) Token.token * (svalue,pos) Token.token -> bool end
(**** Original file: join.sml ****)
(* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)
(* functor Join creates a user parser by putting together a Lexer structure, anLrValuesstructure,andapolymorphicparserstructure.Notethat theLexerandLrValuesstructuremustsharethetypepos(i.e.thetype oflinenumbers),thetypesvaluesforsemanticvalues,andthetype oftokens.
*)
type arg = ParserData.arg type pos = ParserData.pos type result = ParserData.result type svalue = ParserData.svalue val makeLexer = LrParser.Stream.streamify o Lex.makeLexer val parse = fn (lookahead,lexer,error,arg) =>
(fn (a,b) => (ParserData.Actions.extract a,b))
(LrParser.parse {table = ParserData.table,
lexer=lexer,
lookahead=lookahead,
saction = ParserData.Actions.actions,
arg=arg,
void= ParserData.Actions.void,
ec = {is_keyword = ParserData.EC.is_keyword,
noShift = ParserData.EC.noShift,
preferred_change = ParserData.EC.preferred_change,
errtermvalue = ParserData.EC.errtermvalue,
error=error,
showTerminal = ParserData.EC.showTerminal,
terms = ParserData.EC.terms}}
) val sameToken = Token.sameToken end
(* functor JoinWithArg creates a variant of the parser structure produced above.Inthiscase,themakeLexertakeanadditionalargumentbefore yieldingavalueoftypeunit->(svalue,pos)token
*)
type arg = ParserData.arg type lexarg = Lex.UserDeclarations.arg type pos = ParserData.pos type result = ParserData.result type svalue = ParserData.svalue
(* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *) structure LrTable : LR_TABLE = struct open Array List
infix 9sub datatype ('a,'b) pairlist = EMPTY
| PAIR of'a * 'b * ('a,'b) pairlist datatype term = T of int datatype nonterm = NT of int datatype state = STATE of int datatype action = SHIFT of state
| REDUCE of int (* rulenum from grammar *)
| ACCEPT
| ERROR
exception Goto of state * nonterm type table = {states: int, rules : int,initialState: state,
action: ((term,action) pairlist * action) array,
goto : (nonterm,state) pairlist array} val numStates = fn ({states,...} : table) => states val numRules = fn ({rules,...} : table) => rules val describeActions =
fn ({action,...} : table) =>
fn (STATE s) => action sub s val describeGoto =
fn ({goto,...} : table) =>
fn (STATE s) => goto sub s fun findTerm (T term,row,default) = letfunfind (PAIR (T key,data,r)) = if key < term thenfind r elseif key=term then data else default
| find EMPTY = default infind row end fun findNonterm (NT nt,row) = letfunfind (PAIR (NT key,data,r)) = if key < nt thenfind r elseif key=nt then SOME data else NONE
| find EMPTY = NONE infind row end val action = fn ({action,...} : table) =>
fn (STATE state,term) => letval (row,default) = action sub state in findTerm(term,row,default) end val goto = fn ({goto,...} : table) =>
fn (a as (STATE state,nonterm)) => case findNonterm(nonterm,goto sub state) of SOME state => state
| NONE => raise (Goto a) val initialState = fn ({initialState,...} : table) => initialState val mkLrTable = fn {actions,gotos,initialState,numStates,numRules} =>
({action=actions,goto=gotos,
states=numStates,
rules=numRules,
initialState=initialState} : table) end;
(**** Original file: stream.sml ****)
(* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)
(* Stream: a structure implementing a lazy stream. The signature STREAM
is found in base.sig *)
structure Stream :> STREAM = struct datatype'a str = EVAL of 'a * 'a str Unsynchronized.ref | UNEVAL of (unit->'a)
type'a stream = 'a str Unsynchronized.ref
fun get(Unsynchronized.ref(EVAL t)) = t
| get(s as Unsynchronized.ref(UNEVAL f)) = letval t = (f(), Unsynchronized.ref(UNEVAL f)) in s := EVAL t; t end
fun streamify f = Unsynchronized.ref(UNEVAL f) fun cons(a,s) = Unsynchronized.ref(EVAL(a,s))
end;
(**** Original file: parser2.sml ****)
(* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)
(* parser.sml: This is a parser driver for LR tables with an error-recovery routineaddedtoit.Theroutineusedisdescribedindetailinthis article:
val DEBUG1 = false val DEBUG2 = false
exception ParseError
exception ParseImpossible of int
structure Fifo :> FIFO = struct type'a queue = ('a list * 'a list) val empty = (nil,nil)
exception Empty fun get(a::x, y) = (a, (x,y))
| get(nil, nil) = raise Empty
| get(nil, y) = get(rev y, nil) fun put(a,(x,y)) = (x,a::y) end
type ('a,'b) elem = (state * ('a * 'b * 'b)) type ('a,'b) stack = ('a,'b) elem list type ('a,'b) lexv = ('a,'b) token type ('a,'b) lexpair = ('a,'b) lexv * (('a,'b) lexv Stream.stream) type ('a,'b) distanceParse =
('a,'b) lexpair *
('a,'b) stack *
(('a,'b) stack * ('a,'b) lexpair) Fifo.queue *
int ->
('a,'b) lexpair *
('a,'b) stack *
(('a,'b) stack * ('a,'b) lexpair) Fifo.queue *
int *
action option
type ('a,'b) ecRecord =
{is_keyword : term -> bool,
preferred_change : (term list * term list) list,
error : string * 'b * 'b -> unit,
errtermvalue : term -> 'a,
terms : term list,
showTerminal : term -> string,
noShift : term -> bool}
local
val println = fn s => (TextIO.print s; TextIO.print"\n") val showState = fn (STATE s) => "STATE " ^ (Int.toString s) in fun printStack(stack: ('a,'b) stack, n: int) = case stack of (state,_) :: rest =>
(TextIO.print("\t" ^ Int.toString n ^ ": ");
println(showState state);
printStack(rest, n+1))
| nil => ()
fun prAction showTerminal
(stack as (state,_) :: _, next as (TOKEN (term,_),_), action) =
(println "Parse: state stack:";
printStack(stack, 0);
TextIO.print(" state="
^ showState state
^ " next="
^ showTerminal term
^ " action="
); case action of SHIFT state => println ("SHIFT " ^ (showState state))
| REDUCE i => println ("REDUCE " ^ (Int.toString i))
| ERROR => println "ERROR"
| ACCEPT => println "ACCEPT")
| prAction _ (_,_,action) = () end
(* ssParse: parser which maintains the queue of (state * lexvalues) in a steady-state.Ittakesatable,showTerminalfunction,saction function,andfixErrorfunction.ItparsesuntilanACCEPTis encountered,oranexceptionisraised.Whenanerrorisencountered, fixErroriscalledwiththeargumentsofparseStep(lexv,stack,and queue).Itreturnsthelexv,andanewstackandqueueadjustedso
that the lexv can be parsed *)
val ssParse =
fn (table,showTerminal,saction,fixError,arg) => letval prAction = prAction showTerminal val action = LrTable.action table val goto = LrTable.goto table fun parseStep(args as
(lexPair as (TOKEN (terminal, value as (_,leftPos,_)),
lexer
),
stack as (state,_) :: _,
queue)) = letval nextAction = action (state,terminal) val _ = if DEBUG1 then prAction(stack,lexPair,nextAction) else () incase nextAction of SHIFT s => letval newStack = (s,value) :: stack val newLexPair = Stream.get lexer val (_,newQueue) =Fifo.get(Fifo.put((newStack,newLexPair),
queue)) in parseStep(newLexPair,(s,value)::stack,newQueue) end
| REDUCE i =>
(case saction(i,leftPos,stack,arg) of (nonterm,value,stack as (state,_) :: _) =>
parseStep(lexPair,(goto(state,nonterm),value)::stack,
queue)
| _ => raise (ParseImpossible 197))
| ERROR => parseStep(fixError args)
| ACCEPT =>
(case stack of (_,(topvalue,_,_)) :: _ => letval (token,restLexer) = lexPair in (topvalue,Stream.cons(token,restLexer)) end
| _ => raise (ParseImpossible 202)) end
| parseStep _ = raise (ParseImpossible 204) in parseStep end
(* distanceParse: parse until n tokens are shifted, or accept or errorareencountered.Takesatable,showTerminalfunction,and semanticactionfunction.ReturnsaparserwhichtakesalexPair (lexresult*lexer),astatestack,aqueue,andadistance (mustbe>0)toparse.Theparserreturnsanewlex-value,astack withthenthtokenshiftedontop,aqueue,adistance,andaction
option. *)
val distanceParse =
fn (table,showTerminal,saction,arg) => letval prAction = prAction showTerminal val action = LrTable.action table val goto = LrTable.goto table fun parseStep(lexPair,stack,queue,0) = (lexPair,stack,queue,0,NONE)
| parseStep(lexPair as (TOKEN (terminal, value as (_,leftPos,_)),
lexer
),
stack as (state,_) :: _,
queue,distance) = letval nextAction = action(state,terminal) val _ = if DEBUG1 then prAction(stack,lexPair,nextAction) else () incase nextAction of SHIFT s => letval newStack = (s,value) :: stack val newLexPair = Stream.get lexer in parseStep(newLexPair,(s,value)::stack,
Fifo.put((newStack,newLexPair),queue),distance-1) end
| REDUCE i =>
(case saction(i,leftPos,stack,arg) of (nonterm,value,stack as (state,_) :: _) =>
parseStep(lexPair,(goto(state,nonterm),value)::stack,
queue,distance)
| _ => raise (ParseImpossible 240))
| ERROR => (lexPair,stack,queue,distance,SOME nextAction)
| ACCEPT => (lexPair,stack,queue,distance,SOME nextAction) end
| parseStep _ = raise (ParseImpossible 242) in parseStep : ('_a,'_b) distanceParse end
(* mkFixError: function to create fixError function which adjusts parser state
so that parse may continue in the presence of an error *)
(lexv as (TOKEN (term,value as (_,leftPos,_)),_),stack,queue) = letval _ = if DEBUG2 then
error("syntax error found at " ^ (showTerminal term),
leftPos,leftPos) else ()
fun tokAt(t,p) = TOKEN(t,(errtermvalue t,p,p))
val minDelta = 3
(* pull all the state * lexv elements from the queue *)
val stateList = letfun f q = letval (elem,newQueue) = Fifo.get q in elem :: (f newQueue) endhandle Fifo.Empty => nil in f queue end
(* now number elements of stateList, giving distance from
error token *)
val showTerms = String.concat o map (fn TOKEN(t,_) => " " ^ showTerminal t)
val printChange = fn c => letval CHANGE {distance,new,orig,pos,...} = c in (TextIO.print ("{distance= " ^ (Int.toString distance));
TextIO.print (",orig ="); TextIO.print(showTerms orig);
TextIO.print (",new ="); TextIO.print(showTerms new);
TextIO.print (",pos= " ^ (Int.toString pos));
TextIO.print"}\n") end
val printChangeList = app printChange
(* parse: given a lexPair, a stack, and the distance from the error
token, return the distance past the error token that we are able to parse.*)
fun parse (lexPair,stack,queuePos : int) = case distanceParse(lexPair,stack,Fifo.empty,queuePos+maxAdvance+1) of (_,_,_,distance,SOME ACCEPT) => if maxAdvance-distance-1 >= 0 then maxAdvance else maxAdvance-distance-1
| (_,_,_,distance,_) => maxAdvance - distance - 1
(* catList: concatenate results of scanning list *)
fun catList l f = List.foldr (fn(a,r)=> f a @ r) [] l
fun keywordsDelta new = ifList.exists (fn(TOKEN(t,_))=>is_keyword t) new then minDelta else0
fun tryChange{lex,stack,pos,leftPos,rightPos,orig,new} = letval lex' = List.foldr (fn (t',p)=>(t',Stream.cons p)) lex new val distance = parse(lex',stack,pos+length new-length orig) inif distance >= minAdvance + keywordsDelta new then [CHANGE{pos=pos,leftPos=leftPos,rightPos=rightPos,
distance=distance,orig=orig,new=new}] else [] end
(* tryDelete: Try to delete n terminals. Returnsingle-element[success]ornil.
Do not delete unshiftable terminals. *)
fun tryDelete n ((stack,lexPair as (TOKEN(term,(_,l,r)),_)),qPos) = letfun del(0,accum,left,right,lexPair) =
tryChange{lex=lexPair,stack=stack,
pos=qPos,leftPos=left,rightPos=right,
orig=rev accum, new=[]}
| del(n,accum,left,right,(tok as TOKEN(term,(_,_,r)),lexer)) = if noShift term then [] else del(n-1,tok::accum,left,r,Stream.get lexer) in del(n,[],l,r,lexPair) end
(* tryInsert: try to insert tokens before the current terminal;
return a list of the successes *)
fun tryInsert((stack,lexPair as (TOKEN(_,(_,l,_)),_)),queuePos) =
catList terms (fn t =>
tryChange{lex=lexPair,stack=stack,
pos=queuePos,orig=[],new=[tokAt(t,l)],
leftPos=l,rightPos=l})
(* trySubst: try to substitute tokens for the current terminal;
return a list of the successes *)
fun trySubst ((stack,lexPair as (orig as TOKEN (term,(_,l,r)),lexer)),
queuePos) = if noShift term then [] else
catList terms (fn t =>
tryChange{lex=Stream.get lexer,stack=stack,
pos=queuePos,
leftPos=l,rightPos=r,orig=[orig],
new=[tokAt(t,r)]})
(* do_delete(toks,lexPair) tries to delete tokens "toks" from "lexPair". Ifitsucceeds,returnsSOME(toks',l,r,lp),where toks'istheactualtokens(withpositionsandvalues)deleted, (l,r)arethe(leftmost,rightmost)positionoftoks', lpiswhatremainsofthestreamafterdeletion
*) fun do_delete(nil,lp as (TOKEN(_,(_,l,_)),_)) = SOME(nil,l,l,lp)
| do_delete([t],(tok as TOKEN(t',(_,l,r)),lp')) = if eqT (t, t') then SOME([tok],l,r,Stream.get lp') else NONE
| do_delete(t::rest,(tok as TOKEN(t',(_,l,r)),lp')) = if eqT (t,t') thencase do_delete(rest,Stream.get lp') of SOME(deleted,l',r',lp'') =>
SOME(tok::deleted,l,r',lp'')
| NONE => NONE else NONE
fun tryPreferred((stack,lexPair),queuePos) =
catList preferred_change (fn (delete,insert) => ifList.exists noShift delete then [] (* should give warning at
parser-generation time *) elsecase do_delete(delete,lexPair) of SOME(deleted,l,r,lp) =>
tryChange{lex=lp,stack=stack,pos=queuePos,
leftPos=l,rightPos=r,orig=deleted,
new=map (fn t=>(tokAt(t,r))) insert}
| NONE => [])
val findMaxDist = fn l => List.foldr (fn (CHANGE {distance,...},high) => Int.max(distance,high)) 0 l
(* maxDist: max distance past error taken that we could parse *)
val maxDist = findMaxDist changes
(* remove changes which did not parse maxDist tokens past the error token *)
val changes = catList changes
(fn(c as CHANGE{distance,...}) => if distance=maxDist then [c] else [])
incase changes of (l as change :: _) => letfun print_msg (CHANGE {new,orig,leftPos,rightPos,...}) = letval s = case (orig,new) of (_::_,[]) => "deleting " ^ (showTerms orig)
| ([],_::_) => "inserting " ^ (showTerms new)
| _ => "replacing " ^ (showTerms orig) ^ " with " ^ (showTerms new) in error ("syntax error: " ^ s,leftPos,rightPos) end
val _ =
(if length l > 1 andalso DEBUG2 then
(TextIO.print"multiple fixes possible; could fix it by:\n"; app print_msg l;
TextIO.print"chosen correction:\n") else ();
print_msg change)
(* findNth: find nth queue entry from the error entry.ReturnstheNthqueueentryandtheportionof thequeuefromthebeginningtothenth-1entry.The errorentryisattheendofthequeue.
Examples:
queue=abcde findNth0=(e,abcd) findNth1=(d,abc)
*)
val findNth = fn n => letfun f (h::t,0) = (h,rev t)
| f (h::t,n) = f(t,n-1)
| f (nil,_) = let exception FindNth inraise FindNth end in f (rev stateList,n) end
val CHANGE {pos,orig,new,...} = change val (last,queueFront) = findNth pos val (stack,lexPair) = last
val lp1 = List.foldl(fn (_,(_,r)) => Stream.get r) lexPair orig val lp2 = List.foldr(fn(t,r)=>(t,Stream.cons r)) lp1 new
val restQueue =
Fifo.put((stack,lp2), List.foldl Fifo.put Fifo.empty queueFront)
val (lexPair,stack,queue,_,_) =
distanceParse(lp2,stack,restQueue,pos)
in (lexPair,stack,queue) end
| nil => (error("syntax error found at " ^ (showTerminal term),
leftPos,leftPos); raise ParseError) end
val parse = fn {arg,table,lexer,saction,void,lookahead,
ec=ec as {showTerminal,...} : ('_a,'_b) ecRecord} => letval distance = 15(* defer distance tokens *) val minAdvance = 1(* must parse at least 1 token past error *) val maxAdvance = Int.max(lookahead,0)(* max distance for parse check *) val lexPair = Stream.get lexer val (TOKEN (_,(_,leftPos,_)),_) = lexPair val startStack = [(initialState table,(void,leftPos,leftPos))] val startQueue = Fifo.put((startStack,lexPair),Fifo.empty) val distanceParse = distanceParse(table,showTerminal,saction,arg) val fixError = mkFixError(ec,distanceParse,minAdvance,maxAdvance) val ssParse = ssParse(table,showTerminal,saction,fixError,arg) fun loop (lexPair,stack,queue,_,SOME ACCEPT) =
ssParse(lexPair,stack,queue)
| loop (lexPair,stack,queue,0,_) = ssParse(lexPair,stack,queue)
| loop (lexPair,stack,queue,distance,SOME ERROR) = letval (lexPair,stack,queue) = fixError(lexPair,stack,queue) in loop (distanceParse(lexPair,stack,queue,distance)) end
| loop _ = let exception ParseInternal inraise ParseInternal end in loop (distanceParse(lexPair,startStack,startQueue,distance)) end end;
;
Messung V0.5 in Prozent
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.26Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-09-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Sekunden
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.