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

Self syntax (long)




Ivan Moore <ivan@cs.man.ac.uk> wrote on Fri, 27 May 94 13:39:21 BST:
> Does anyone have a Self parser (written in Self) that they would let me use?
> 
> thanks in advance,
   
I have a parser in C that I plan to rewrite in Self soon. Actually, the
only reason why I did it in C first is that my access to Self is very
limited. Meanwhile, you might get some use out of the syntax below.
Its main problem is that it doesn't work, but I found it easier to do
some ugly hacks in the parser rather than fixing the syntax. It is
easy to see that this is an adaptation of the parser in parser.self.
Some problems are:

1) resend - this has several problems. First of all, it interacts with
   the lexical scanner ( shown here as the <nowhite> token ). Another
   problem is that it overloads ".", which is already complicated by
   its use in numbers and at the end of expressions. But the real
   error in the syntax is that <resend> appears three times in a way
   that makes it necessary to look ahead many tokens. A very ugly hack
   was saving the "lastResend" in a global variable and using that
   when trying to match <resend> again in the same position in the
   input stream. Note that the <resend> may be empty and this means
   an implicit self receiver. Note that <nowhite> actually means no
   blanks, newlines, etc. and no delimiters either.

2) "-" - this is very nasty when followed by a number. You have to make
   the scanner work with the parser to find out if this is part of
   the number or not ( this is mentioned in the manual ).

3) "|" - you just have to note ( again in the manual ) that while
   binary selectors can have this character, by itself it is a delimiter 
   and not an binary selector.

4) inner methods - the syntax shown accepts inner methods that were
   eliminated in Self 2.0. I found it easier to write a quick hack
   to get rid of them.

5) keyword arguments - the syntax itself does not garantee that
   if you use the "cL" syntax for declaring a keyword slot that
   the arguments will be declared inside the method. You have to
   add an extra check for that ( which is wise anyway to check
   the number of arguments ).

With these hacks I was able to parse all of the Self 3.0 files ( though
it did complain of an extra "." in init.self ). Here is the syntax:

   expression ::= keyMess

   keyMess    ::= binMess ( kMess | <empty> ) |
		  resend kMess

   kMess      ::= smallKey argList

   argList    ::= keyMess ( capKey argList | <empty> )

   binMess    ::= unaryMess bList |
		  resend bMess bList

   bList      ::= bMess bList |
		  <empty>

   bMess      ::= operator ( unaryMess | keyMess )

   unaryMess  ::= primary ( uMess | <empty> )
		  resend uMess

   uMess      ::= identifier ( uMess | <empty> )

   resend     ::= "resend." <nowhite> |
		  identifier "." <nowhite> |
		  <empty>

   primary    ::= "self" |
		  number |
		  string |
		  method |
		  block  |
		  annotation

   method     ::= "(" slotList code ")"

   block      ::= "[" slotList code "]"

   annotation ::= "{" string primary "}"

   code       ::= "^" expression ( "." | <empty> ) |
		  expression ( "." code | <empty> ) |
		  <empty>

   slotList   ::= "|" sList |
		  <empty>

   sList      ::= "|" |
		  annotSlots sList |
		  slot ( "." sList | "|" )

   annotSlots ::= "{" string annotList

   annotList  ::= "}" |
		  annotSlots annotList |
		  slot ( "." annotList | "}" )

   slot       ::= privacy ( argSlot | dataSlot | bSlot | kSlot )

   privacy    ::= "^" |
		  "_" |
		  "^_" |
		  "_^" |
		  <empty>

   argSlot    ::= ":" identifier 

   dataSlot   ::= slotName ( "<-" expression | "=" expression | <empty> )

   bSlot      ::= operator ( "=" method | identifier "=" method )

   kslot      ::= smallKeyword ( identifier ceL "=" method | cL "=" method )

   cL         ::= capKeyword cL |
		  <empty>

   ceL        ::= capKeyword identifier ceL |
		  <empty>

   slotName   ::= identifier priority

   priority   ::= "*" |
		  <empty>

- Jecel