On Mar 12, 2010, at 9:00 AM, steven Hooley wrote:

>> Bloomin' magic! Thanks, Filip, it worketh well. Hardy souls all.
>> Tom W.
> 
> Is it possible to see an example of how this might be used? I'd like
> to understand Bison/Yacc better and i think an example relevant to
> Cocoa / Objective-C would really help.
> 
> Thanks,
> Steven


Steve,

The interpreter I am working on is a work in progress, but here is a copy of 
the yacc/bison file as it exists as I start work on it today. It imports (not 
includes) the Cocoa Foundation and the semantic actions are written in 
Objective-C. This file is incomplete as it is only two days old and I am in the 
process of writing the semantic actions for the statement and expression types 
now. But you can still see the statement and expression types that will be 
handled by reading the grammar. The language itself is nearly complete. As it 
stands now it has only one shift/reduce conflict, that caused by the inherent 
ambiguity in the if/else statement, but the yacc/bison approach to resolving 
these conflicts by using shift is the proper handling in this case. (All this 
means is that the parser will make sure that else statements bind to the 
closest "then" part.)

This is a typical example of using yacc/bison. The language defined is a 
general purpose programming language. During parsing a semantic tree of the 
program is built out of Objective-C objects (including the representations of 
different kinds of statements and expressions, values, types, modules and so 
on). Building the tree is what the semantic actions (the code with the $$ and 
$1 things scattered among the rules) do. Once this representation is built, the 
tree is validated for programming errors as any normal compiler would do (for 
example, undeclared variables, argument/parameter mismatches, assigning a 
number to a set, and so on) and then the program is run by an interpreter. The 
interpreter is similar to, though much simpler than, the Java virtual machine, 
as it executes the semantic trees as if they were instructions to a virtual 
machine, while managing the run time stack and the currently active subtree of 
symbol tables. I am writing the validator and interpreter in parallel with the 
parser, so there is a lot of stuff not visible here.

This is all part of a Cocoa-based genealogical software application, where this 
part allows users to run their own algorithms on records in their databases or 
to generate their own specialty reports without having to modify the 
application itself. The genealogical records (eg, info about events, persons, 
families, and so on) are all kept in tree structures that can be represented in 
the application's databases or externally as XML or other types of structured 
text (GEDCOM is the format often chosen for genealogical software but it 
suffers from a variety of limitations.) Thus my earlier and not so positive 
reference to XSLT, which is the "official" (and much harder) way to do this, 
though I expect that an XSLT "program" would not be able to affect the database 
holding the records it processes.

Needless to say I am extremely pleased that all I had to do was make the suffix 
to the yacc file be .ym instead of .y to get Xcode to do all the right things. 
I don't know whether bison itself was modified or whether the Xcode build rules 
just do the proper renaming, but the fact that someone at Apple worried about 
it and then made it work, is just one of those little things that makes me so 
content, one might even say smirkily self-satisfied, to be developing for the 
Mac. And then the fact that someone on this list (thanks, Filip) knew this was 
even better, as I have yet to find any actual DOCUMENTATION that states that 
this would happen! Easter eggs in spring.

Tom Wetmore, Chief Bottle Washer, DeadEnds Software

//  Interpreter.ym
//
//  Created by Thomas Wetmore on 3/10/2010.
//  Last changed on 3/12/2010.
//  Copyright 2010 DeadEnds Software. All rights reserved.

%{
#import <Foundation/Foundation.h>
#import "TWInterpreter.h"
#import "TWInterpStatement.h"
#import "TWInterpExpression.h"
#import "TWInterpModule.h"
#import "TWInterpLexer.h"

// For this parser every semantic type is an Objective-C object.
#define YYSTYPE id
        
extern TWInterpreterLexer* lexer;
void yyerror (char* message);
int yylex ();
%}

%token  TYPE
%right  ASGNOP
%left   OROP
%left   ANDOP
%left   EQOP
%left   RELOP
%left   ADDOP
%left   MULOP
%right  UNARYOP
%right  NOTOP
%token  IDEN ICONS FCONS SCONS BCONS
%token  WHILE DO IF ELSE
%token  BREAK CONTINUE RETURN

%%

definitions     :       definition
                        |       definitions definition
                        ;

definition      :       declaration {
                                        [globalDeclarations addObject: $1];
                                }
                        |       module {
                                        [moduleTable setObject: $1 forKey: 
((TWInterpModule*)$1).name];
                                }
                        ;

declaration     :       TYPE identifiers m ';' {
                                        $$ = [[[TWInterpDeclaration alloc] 
initWithType: $1 variables: $2] autorelease];
                                        ((TWInterpStatement*) $$).lineNumber = 
$3;
                                }
                        ;

module          :       TYPE IDEN '(' parameterso ')' block {
                                        $$ = [[[TWInterpModule alloc] 
initWithType: $1 name: $2 parameters: $4 block: $6] autorelease];
                                }
                        ;

declarationso:  declarations {
                                        $$ = $1;
                                }
                        |       /* empty */ {
                                        $$ = nil;
                                }
                        ;

declarations:   declaration {
                                        $$ = [[[NSMutableArray alloc] 
initWithObjects: $1, nil] autorelease];
                                }
                        |       declarations declaration {
                                        $$ = $1; [$$ addObject: $2];
                                }
                        ;

identifiers     :       IDEN {
                                        $$ = [[[NSMutableArray alloc] 
initWithObjects: $1, nil] autorelease];
                                }
                        |       identifiers ',' IDEN {
                                        $$ = $1; [$$ addObject: $3];
                                }
                        ;

parameterso     :       parameters {
                                        $$ = $1;
                                }
                        |       /* empty */ {
                                        $$ = nil;
                                }
                        ;

parameters      :       parameter {
                                        $$ = [[[NSMutableArray alloc] 
initWithObjects: $1, nil] autorelease];
                                }
                        |       parameters ',' parameter {
                                        $$ = $1; [$$ addObject: $3];
                                }
                        ;

parameter       :       TYPE IDEN
                        ;

statementso     :       statements {
                                        $$ = $1;
                                }
                        |       /* empty */ {
                                        $$ = nil;
                                }
                        ;

statements      :       statement {
                                        $$ = [[[NSMutableArray alloc] 
initWithObjects: $1, nil] autorelease];
                                }
                        |       statements statement {
                                        $$ = $1; [$$ addObject: $2];
                                }
                        ;

statement       :       expression m ';'
                        |       IF m '(' expression ')' statement
                        |       IF m '(' expression ')' statement ELSE statement
                        |       WHILE m '(' expression ')' statement
                        |       DO m statement WHILE '(' expression ')'
                        |       block
                        |       RETURN m expressiono ';'
                        |       CONTINUE m ';'
                        |       BREAK m ';'
                        ;

block           :       '{' declarationso statementso '}' {
                                        $$ = [[[TWInterpBlockStatement alloc] 
initWithDeclaractions: $2 statements: $3] autorelease];
                                }
                        ;

expression      :       IDEN
                        |       ICONS
                        |       FCONS
                        |       SCONS
                        |       BCONS
                        |       '(' expression ')'
                        |       IDEN '(' expressionso ')'
                        |       expression ADDOP expression
                        |       expression MULOP expression
                        |       expression RELOP expression
                        |       expression EQOP expression
                        |       expression ANDOP expression
                        |       expression OROP expression
                        |       expression ASGNOP expression
                        |       ADDOP expression %prec UNARYOP
                        |       NOTOP expression
                        ;

expressiono     :       expression
                        |       /* empty */
                        ;

expressionso:   expressions
                        |       /* empty */
                        ;

expressions     :       expression
                        |       expressions ',' expression
                        ;

m                       :       /* empty */ {
                                        $$ = [[[NSNumber alloc] initWithInt: 
lexer.lineNumber] autorelease];
                                }
%%

_______________________________________________

Cocoa-dev mailing list ([email protected])

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to