Hi David,

well, in real OMeta it would look like this:

  fullname = name:first name:last          -> new Name(first, last)
           | name:first name:mid name:last -> new Name(first, last)

  ^ Rule name  ^ Rule itself                  ^ Action

Speaking of this syntax, please note that the code I submitted is not a
full OMeta implementation that allows to write grammar this way, but
just a parser framework using PEGs, which may be useful for building
one. In addition to the simple parsing, OMeta (the *real* OMeta) also
has this nice analogy that a grammar is very much like a class in that
you can "subclass" it, extend it, "call" rules of the superclass etc.
I fell very honored about your enthusiastic entry on the news page :-),
but I'd be happy if you could correct that there.

Okay, back to the actions:
In the above example (lower line), you can see that the rule 'name' is
invoked three times, binding the result to the variables 'first', 'mid',
and 'last'. The actions on the right are written in the 'host language',
Smalltalk for example, and may use the bound variables.

The 'alternative' operator '|' has lower precedence than '->'.
'->' has lower precendence than the remaining operators.

'=' is the equivalent to '::=' in usual BNF syntax.

Many examples can be found on
http://www.tinlizzie.org/ometa-js/#Toylog
(Click the chooser on the top right to enter other projects)

As our implementation doesn't have the nice OMeta syntax yet, rules need
to be written differently. The above rule can be written as:

 nameExpr := OMAlphabeticExpr new + OMAlphabeticExpr new repeated.

 upperPart := (nameExpr/'f') + (nameExpr/'l') instantiating: [ :d |
   "d is a dictionary mapping 'f' and 'l' to their matched results"
   Name new initWithFirst: (d at: 'f') withLast: (d at: 'l')
 ].
 lowerPart := .... "Similar."
 fullNameExpr := upperPart or: lowerPart.

The "operators" can be found below the line "Just for convenience,
a few helpers". They're really just for convenient testing, though.
Utimately, a parser for the OMeta grammar syntax will provide much nicer
syntax and not need to use them. It is probably worthwhile however to
just use the syntax for now and convert grammars to real OMeta syntax
when it is supported. ;-)

In the Smalltalk example above, the message attaching the action to a
parsing expression in #instantiating:. The method #instantiating:
returns the same parsing expression as the receiver expression, but the
returned expression differs in that its parsing results are first
"instantiated" with the closure. (I like to view those anonymous
functions as a fancy way to give an expression with the bound variables
here, or a "skeleton" expression which can be instantiated over these
bound variables.)

I hope that clears things up a bit. I'm happy you can use the code. :-)

Best regards,
Guenther

PS: I CC'd this to etoile-dev.

On Sun, Jan 10, 2010 at 02:51:16PM +0000, David Chisnall wrote:
> Hi G?nther,
> 
> I'm wondering how you attach actions to expressions in OMeta.   
> Eventually I'll want to produce LK AST nodes from OMeta, but I was  
> thinking first that I'd like to use it to convert Objective-C type  
> encodings to Objective-C code, so that I can write an AST visitor  
> using OMeta that dumps a header file containing @interface  
> declarations for all of the methods defined in an AST.
> 
> David
> 
> -- Sent from my STANTEC-ZEBRA
> 

_______________________________________________
Etoile-dev mailing list
Etoile-dev@gna.org
https://mail.gna.org/listinfo/etoile-dev

Reply via email to