[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