[m-rev.] Re: [m-dev.] '|' as an operator

David Overton dmo at cs.mu.OZ.AU
Wed Feb 12 11:48:23 AEDT 2003


On Tue, Feb 11, 2003 at 05:52:41PM +1100, Fergus Henderson wrote:
> I think that change will slow down parsing significantly.  Firstly,
> you've added another field to the parser state, which will increase by
> 20% the amount of memory that it allocates for parser states.  Secondly,
> you've added an new test every time it gets a token or peeks at a token.
> These both seem like a fairly high price to pay.  I don't think it is
> worth it.
> 
> There are advantages to sticking with a syntax that can be parsed
> easily by standard Prolog.  Why don't you just use a different operator?
> 
> But if you are really committed to using a non-standard-Prolog syntax,
> a more efficient and IMHO more elegant approach to implementing it would
> be to change the `IsArg' argument from a boolean to an enumeration of
> the different possible states -- an ordinary term, a list element, or an
> argument.  That can then be used instead of the `in_list_context' field.

Okay, here are some times which suggest it doesn't make much difference
either way.  But I have implemented the change you suggested.  I agree
that it is more elegant and simpler.

Time for compiling make_hlds.m.

Original:
	17.340u 0.460s 0:19.79 89.9%	0+0k 0+0io 2992pf+0w
	17.490u 0.300s 0:18.72 95.0%	0+0k 0+0io 2992pf+0w

My first change:
	17.320u 0.470s 0:19.74 90.1%	0+0k 0+0io 2987pf+0w
	17.440u 0.280s 0:18.20 97.3%	0+0k 0+0io 2987pf+0w

Change suggested by Fergus:
	17.430u 0.450s 0:18.64 95.9%	0+0k 0+0io 2983pf+0w
	17.360u 0.410s 0:19.00 93.5%	0+0k 0+0io 2983pf+0w

Index: parser.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/parser.m,v
retrieving revision 1.38
diff -u -r1.38 parser.m
--- parser.m	8 Nov 2001 15:30:38 -0000	1.38
+++ parser.m	12 Feb 2003 00:38:26 -0000
@@ -132,6 +132,12 @@
 	--->	ok(T)
 	;	error(string, token_list).
 
+	% Are we parsing an ordinary term, an argument or a list element?
+:- type term_kind
+	--->	ordinary_term
+	;	argument
+	;	list_elem.
+
 %-----------------------------------------------------------------------------%
 
 parser__read_term(Result) -->
@@ -285,7 +291,8 @@
 
 parser__parse_term(Term) -->
 	parser__get_ops_table(OpTable),
-	parser__parse_term_2(ops__max_priority(OpTable) + 1, no, Term).
+	parser__parse_term_2(ops__max_priority(OpTable) + 1, ordinary_term,
+		Term).
 
 :- pred parser__parse_arg(parse(term(T)), parser__state(Ops, T),
 		parser__state(Ops, T)) <= op_table(Ops).
@@ -293,27 +300,36 @@
 
 parser__parse_arg(Term) -->
 	parser__get_ops_table(OpTable),
-	parser__parse_term_2(ops__arg_priority(OpTable), yes, Term).
+	parser__parse_term_2(ops__arg_priority(OpTable), argument, Term).
+
 
-:- pred parser__parse_term_2(int, bool, parse(term(T)),
+:- pred parser__parse_list_elem(parse(term(T)), parser__state(Ops, T),
+		parser__state(Ops, T)) <= op_table(Ops).
+:- mode parser__parse_list_elem(out, in, out) is det.
+
+parser__parse_list_elem(Term) -->
+	parser__get_ops_table(OpTable),
+	parser__parse_term_2(ops__arg_priority(OpTable), list_elem, Term).
+
+:- pred parser__parse_term_2(int, term_kind, parse(term(T)),
 	parser__state(Ops, T), parser__state(Ops, T)) <= op_table(Ops).
 :- mode parser__parse_term_2(in, in, out, in, out) is det.
 
-parser__parse_term_2(MaxPriority, IsArg, Term) -->
-	parser__parse_left_term(MaxPriority, IsArg, LeftPriority, LeftTerm0),
+parser__parse_term_2(MaxPriority, TermKind, Term) -->
+	parser__parse_left_term(MaxPriority, TermKind, LeftPriority, LeftTerm0),
 	( { LeftTerm0 = ok(LeftTerm) } ->
-		parser__parse_rest(MaxPriority, IsArg, LeftPriority, LeftTerm,
-			Term)
+		parser__parse_rest(MaxPriority, TermKind, LeftPriority,
+			LeftTerm, Term)
 	;
 		% propagate error upwards
 		{ Term = LeftTerm0 }
 	).
 
-:- pred parser__parse_left_term(int, bool, int, parse(term(T)),
+:- pred parser__parse_left_term(int, term_kind, int, parse(term(T)),
 	parser__state(Ops, T), parser__state(Ops, T)) <= op_table(Ops).
 :- mode parser__parse_left_term(in, in, out, out, in, out) is det.
 
-parser__parse_left_term(MaxPriority, IsArg, OpPriority, Term) -->
+parser__parse_left_term(MaxPriority, TermKind, OpPriority, Term) -->
 	( parser__get_token(Token, Context) ->
 		(
 			% check for unary minus of integer
@@ -351,10 +367,11 @@
 			{ parser__adjust_priority(RightRightAssoc,
 					BinOpPriority, RightRightPriority) },
 			{ OpPriority = BinOpPriority },
-			parser__parse_term_2(RightPriority, IsArg, RightResult),
+			parser__parse_term_2(RightPriority, TermKind,
+				RightResult),
 			( { RightResult = ok(RightTerm) } ->
-				parser__parse_term_2(RightRightPriority, IsArg,
-							RightRightResult),
+				parser__parse_term_2(RightRightPriority,
+					TermKind, RightRightResult),
 				( { RightRightResult = ok(RightRightTerm) } ->
 					parser__get_term_context(Context,
 						TermContext),
@@ -383,7 +400,8 @@
 		->
 			{ parser__adjust_priority(RightAssoc, UnOpPriority,
 							RightPriority) },
-			parser__parse_term_2(RightPriority, IsArg, RightResult),
+			parser__parse_term_2(RightPriority, TermKind,
+				RightResult),
 			{ OpPriority = UnOpPriority },
 			( { RightResult = ok(RightTerm) } ->
 				parser__get_term_context(Context, TermContext),
@@ -404,17 +422,23 @@
 		{ OpPriority = 0 }
 	).
 
-:- pred parser__parse_rest(int, bool, int, term(T), parse(term(T)),
+:- pred parser__parse_rest(int, term_kind, int, term(T), parse(term(T)),
 	parser__state(Ops, T), parser__state(Ops, T)) <= op_table(Ops).
 :- mode parser__parse_rest(in, in, in, in, out, in, out) is det.
 
-parser__parse_rest(MaxPriority, IsArg, LeftPriority, LeftTerm, Term) -->
+parser__parse_rest(MaxPriority, TermKind, LeftPriority, LeftTerm, Term) -->
 	(
 		% infix op
 		parser__get_token(Token, Context),
-		{ Token = comma, IsArg = no ->
+		{
+			Token = comma,
+			TermKind = ordinary_term,
 			Op0 = ","
 		;
+			Token = ht_sep,
+			TermKind \= list_elem,
+			Op0 = "|"
+		;
 			Token = name(Op0)
 		},
 		(
@@ -454,14 +478,14 @@
 	->
 		{ parser__adjust_priority(RightAssoc, OpPriority,
 					RightPriority) },
-		parser__parse_term_2(RightPriority, IsArg, RightTerm0),
+		parser__parse_term_2(RightPriority, TermKind, RightTerm0),
 		( { RightTerm0 = ok(RightTerm) } ->
 			parser__get_term_context(Context, TermContext),
 			{ OpTerm = term__functor(term__atom(Op),
 				list__append(VariableTerm,
 					[LeftTerm, RightTerm]),
 				TermContext) },
-			parser__parse_rest(MaxPriority, IsArg, OpPriority,
+			parser__parse_rest(MaxPriority, TermKind, OpPriority,
 				OpTerm, Term)
 		;
 			% propagate error upwards
@@ -478,7 +502,8 @@
 		parser__get_term_context(Context, TermContext),
 		{ OpTerm = term__functor(term__atom(Op), [LeftTerm],
 			TermContext) },
-		parser__parse_rest(MaxPriority, IsArg, OpPriority, OpTerm, Term)
+		parser__parse_rest(MaxPriority, TermKind, OpPriority, OpTerm,
+			Term)
 	;
 		{ Term = ok(LeftTerm) }
 	).
@@ -673,7 +698,7 @@
 :- mode parser__parse_list(out, in, out) is det.
 
 parser__parse_list(List) -->
-	parser__parse_arg(Arg0),
+	parser__parse_list_elem(Arg0),
 	( { Arg0 = ok(Arg) } ->
 	    ( parser__get_token(Token, Context) ->
 		parser__get_term_context(Context, TermContext),

-- 
David Overton                  Uni of Melbourne     +61 3 8344 1354
dmo at cs.mu.oz.au                Monash Uni (Clayton) +61 3 9905 5779
http://www.cs.mu.oz.au/~dmo    Mobile Phone         +61 4 0337 4393
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list