[m-rev.] for review: make parsing tail recursive
Peter Wang
novalazy at gmail.com
Wed May 7 14:17:55 AEST 2008
On 2008-05-07, Paul Bone <pbone at csse.unimelb.edu.au> wrote:
> On Wed, May 07, 2008 at 10:41:05AM +1000, Peter Wang wrote:
> > diff -u -r1.58 parser.m
> > --- library/parser.m 3 Apr 2008 05:26:47 -0000 1.58
> > +++ library/parser.m 7 May 2008 00:37:32 -0000
> > @@ -251,7 +251,13 @@
> >
> > :- pred check_for_bad_token(token_list::in, string::out, int::out) is semidet.
> >
> > -check_for_bad_token(token_cons(Token, LineNum, Tokens), Message, LineNum) :-
> > +check_for_bad_token(Token, Message, LineNum) :-
> > + check_for_bad_token_2(Token, Message),
> > + Token = token_cons(_, LineNum, _).
> > +
> > +:- pred check_for_bad_token_2(token_list::in, string::out) is semidet.
> > +
> > +check_for_bad_token_2(token_cons(Token, _LineNum, Tokens), Message) :-
> > ( Token = io_error(IO_Error) ->
> > io.error_message(IO_Error, IO_ErrorMessage),
> > string.append("I/O error: ", IO_ErrorMessage, Message)
> > @@ -264,7 +270,7 @@
> > ; Token = error(ErrorMessage) ->
> > string.append("Syntax error: ", ErrorMessage, Message)
> > ;
> > - check_for_bad_token(Tokens, Message, LineNum)
> > + check_for_bad_token_2(Tokens, Message)
> > ).
> >
>
> This does not return the correct LineNum for the bad token, rather it
> returns the list head's LineNum.
Yes, it did look strange. I think you're right about the intended
behaviour, and the non-tail-call was simply an oversight when the
recursive call was added. I haven't been able to make a test case where
the compiler reports a syntax error on the wrong line though.
Index: library/parser.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/parser.m,v
retrieving revision 1.58
diff -u -r1.58 parser.m
--- library/parser.m 3 Apr 2008 05:26:47 -0000 1.58
+++ library/parser.m 7 May 2008 03:56:16 -0000
@@ -251,21 +251,26 @@
:- pred check_for_bad_token(token_list::in, string::out, int::out) is semidet.
-check_for_bad_token(token_cons(Token, LineNum, Tokens), Message, LineNum) :-
+check_for_bad_token(token_cons(Token, LineNum0, Tokens), Message, LineNum) :-
( Token = io_error(IO_Error) ->
io.error_message(IO_Error, IO_ErrorMessage),
- string.append("I/O error: ", IO_ErrorMessage, Message)
+ string.append("I/O error: ", IO_ErrorMessage, Message),
+ LineNum = LineNum0
; Token = junk(Char) ->
char.to_int(Char, Code),
string.int_to_base_string(Code, 10, Decimal),
string.int_to_base_string(Code, 16, Hex),
string.append_list(["Syntax error: Illegal character 0x", Hex,
- " (", Decimal, ") in input"], Message)
+ " (", Decimal, ") in input"], Message),
+ LineNum = LineNum0
; Token = error(ErrorMessage) ->
- string.append("Syntax error: ", ErrorMessage, Message)
+ string.append("Syntax error: ", ErrorMessage, Message),
+ LineNum = LineNum0
;
check_for_bad_token(Tokens, Message, LineNum)
).
+check_for_bad_token(token_nil, _, _) :-
+ fail.
:- pred parse_whole_term(parse(term(T))::out,
state(Ops, T)::in, state(Ops, T)::out) is det <= op_table(Ops).
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list