1 (* ML
-Yacc Parser
Generator (c
) 1989 Andrew W
. Appel
, David R
. Tarditi
*)
3 (* drt (12/15/89) -- the
functor should be used during development work
,
4 but it is wastes space
in the release version
.
6 functor ParserGen(structure LrTable
: LR_TABLE
7 structure Stream
: STREAM
) : LR_PARSER
=
10 structure LrParser
:> LR_PARSER
=
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
=
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
'
30 type ('a
,'b
) elem
= (state
* ('a
* 'b
* 'b
))
31 type ('a
,'b
) stack
= ('a
,'b
) elem list
33 val showState
= fn (STATE s
) => ("STATE " ^
(makestring s
))
35 fun printStack(stack
: ('a
,'b
) elem list
, n
: int) =
37 of (state
, _
) :: rest
=>
38 (print(" " ^ makestring n ^
": ");
39 println(showState state
);
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
,
50 ec
= {is_keyword
,preferred_change
,
51 errtermvalue
,showTerminal
,
54 let fun prAction(stack
as (state
, _
) :: _
,
55 next
as (TOKEN (term
,_
),_
), action
) =
56 (println
"Parse: state stack:";
65 of SHIFT s
=> println ("SHIFT " ^ showState s
)
66 | REDUCE i
=> println ("REDUCE " ^
(makestring i
))
67 | ERROR
=> println
"ERROR"
68 | ACCEPT
=> println
"ACCEPT";
70 |
prAction (_
,_
,action
) = action
72 val action
= LrTable
.action table
73 val goto
= LrTable
.goto table
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
)
82 let val (nonterm
,value
,stack
as (state
,_
) :: _
) =
83 saction(i
,leftPos
,stack
,arg
)
84 in parseStep(next
,(goto(state
,nonterm
),value
)::stack
)
86 | ERROR
=> let val (_
,leftPos
,rightPos
) = value
87 in error("syntax error\n",leftPos
,rightPos
);
90 | ACCEPT
=> let val (_
,(topvalue
,_
,_
)) :: _
= stack
91 val (token
,restLexer
) = next
92 in (topvalue
,Stream
.cons(token
,lexer
))
94 val next
as (TOKEN (terminal
,(_
,leftPos
,_
)),_
) = Stream
.get lexer
95 in parseStep(next
,[(initialState table
,(void
,leftPos
,leftPos
))])