[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