[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Priorities of (non)operators.



Original-Via: uk.ac.ukc; Mon, 11 Mar 91 18:43:19 GMT
From: Kent Karlsson <kent@se.chalmers.cs>
Date: Mon, 11 Mar 91 19:34:32 +0100
To: haskell@cs.glasgow.ac.uk
Subject: Priorities of (non)operators.
Original-Sender: kent%se.chalmers.cs@sunic.sunet.se
Sender: haskell-request@cs.glasgow.ac.uk


		PRIORITIES OF NONOPERATORS
		==========================

The priorities of some nonoperators are not entierly clear
from the report.
   E.g. how is     if a then b else  \x -> c  where {...} 
supposed to be read:
(i)   as          (if a then b else  \x -> c) where {...}
(ii)  or as        if a then b else (\x -> c  where {...})
(iii) or is it a syntax error, i.e., does one have to
write out the parenthesis?  (Remember that
conditional expressions are supposed to bind tighter than where-expressions,
but lambda-abstractions are supposed to bind looser  than where-expressions...)

   I vote for (iii): it's clearer, and the grammar is easier than
for the other alternatives.

   In order to make the priorities entierly clear, they should be
built into the context-free grammar.  For convenience a production
  exp(k) -> ...   is written as   exp -> ... (k)  below, and any
occurrence of  exp  in an rhs of a grammar production means  exp(-8).
The priorities of operators are sometimes multiplied by 2 below, 
that is in order to handle nonassociative operators properly.
Expressions of the form
	exp(2i+1) rop(i) exp(2i) lop(i) exp(2i+1)
are ambiguous in the grammar below, and therefore disallowed.

   I propose the following grammar for expressions:

lop(i) -> op	(if op is left  associative of priority i)	\
rop(i) -> op	(if op is right associative of priority i)	} (0 <= i <= 9)
nop(i) -> op	(if op is    nonassociative of priority i)	/

exp	->  aexp				(21)
	|   exp(20) exp(21)			(20)	function application, priority 10
	|   exp1(2i)   lop(i) exp2(2i+1)	(2i)	operator application
	|   - exp(13)				(12)	unary -, priority 6
	|   exp1(2i+1) rop(i) exp2(2i)		(2i)	operator application
	|   exp1(2i+1) nop(i) exp2(2i+1)	(2i-1)	operator application
	|   exp(-2) :: [context =>] atype	(-2)	expression type signature
	|   case exp of { alts }		(-4)	case expression
	|   if exp1 then exp2(-4) else exp3(-4)	(-4)	conditional expression
	|   exp(-6) where { decls }		(-6)	where expression
	|   \ apat1 ... apatn [gd] -> exp(-8)	(-8)	lambda abstraction, (n>=0)
	|   exp(j+1)				(j)	priority scheme (-8 <= j < 21)

and similarly for pat and lhs.

   The restriction in the then-part of a conditional expression
is intentionally the same as in the else-part above, even though there
is no ambiguity that is resolved by the restriction.  It is there
just to make the then- and else-parts into the same syntactic category.

   I don't know why   case e of {...} x y z   is a permitted application,
while   f case e of {...}   is not allowed.  I think they are equally ugly,
and so is  case e of {...} + 5  etc.  I've taken the liberty to disallow them
above (but they can still be written *with* parenthesis).

   There are parsing algorithms that implement such a priority scheme
without having the  exp(j) -> exp(j+1)  productions explicit (e.g. the
one used in Isabelle).  (Unfortunately yacc doesn't, but that is yacc's
problem, not a problem in e.g. LR-parsing as such.)

			/kent k