home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource4
/
232_01
/
parser.y
< prev
next >
Wrap
Text File
|
1987-06-17
|
12KB
|
419 lines
/*
Little Smalltalk Class method syntax
differs from smalltalk-80 slightly
class heading is different
vertical bar must appear between methods
syntax for primitives is different
*/
/* literals */
%token LITNUM LITFNUM LITCHAR LITSTR LITSYM
/* basic objects */
%token CLASS ASSIGN BINARY PRIMITIVE NAMEDPRIM
/* types of variables */
%token PSEUDO UPPERCASEVAR LOWERCASEVAR COLONVAR KEYWORD
/* one character symbols */
%token LP RP LB RB PERIOD BAR MBAR SEMI UPARROW PS MINUS PE
/* ( ) [ ] . | ^| ; ^ # - > */
%{
# include "env.h"
# include "drive.h"
# include "parser.h"
%}
%union {
struct litlist *a;
struct blockstruct *b;
char *c;
struct exprstruct *e;
int i;
struct keylist *k;
struct classstruct *l;
struct methodstruct *m;
struct objstruct *o;
enum pseuvars p;
struct primlist *r;
struct statestruct *s;
struct litstruct *t;
struct primstruct *u
}
%{
extern struct blockstruct *mkblock();
extern struct classstruct *mkclass();
extern struct varstruct *mkvar(), *addvlist(), *invlist();
extern struct methodstruct *mkmethod();
extern struct exprstruct *mkexpr(), *mkkey();
extern struct keylist *mkklist();
extern struct statestruct *mkstate();
extern struct objstruct *mkobj();
extern struct primstruct *mkprim();
extern struct primlist *addprim();
extern struct litstruct *mklit();
extern struct litlist *addlit();
extern char *bincat();
struct varstruct *instvars;
struct varstruct *contextvars;
int bytetop = 0;
uchar bytearray[1000];
YYSTYPE e;
int errorcount = 0;
%}
%type <a> litarray
%type <b> block
%type <c> CLASS KEYWORD LOWERCASEVAR UPPERCASEVAR COLONVAR LITSYM LITSTR
%type <c> BINARY BAR MINUS UPARROW PE
%type <c> classname binarysym binarychar
%type <c> LITFNUM fliteral
%type <e> pattern expression cexpression binary unary
%type <e> kcontinuation bcontinuation ucontinuation
%type <i> LITCHAR LITNUM PRIMITIVE NAMEDPRIM
%type <i> tempvars cvarlist namelist barglist nliteral
%type <k> keypattern keywordlist
%type <l> super classheading
%type <m> method methodlist
%type <o> primary
%type <p> PSEUDO
%type <r> objlist
%type <s> statelist statement sexpression opmessagelist
%type <s> bstatelist bstatement bexpression
%type <t> literal iliteral aliteral
%type <u> primitive
%start file
%%
file : classdef
| file classdef
;
classdef: classheading lb methodlist RB
{if (errorcount == 0) genclass($1, $3);}
;
lb : LB
| error {if ((yytext[0] == ':') ||
isalpha(yytext[0])) expect(":SuperClass");
else expect("open brace [");}
;
classheading: class super instancevars {$$ = $2;}
;
class : CLASS
| error {expect("keyword Class");}
;
super : classname {$$ = mkclass($1, (char *) 0);}
| classname COLONVAR {$$ = mkclass($1, $2);}
| error {expect("Classname :Superclass");
$$ = mkclass("Error", (char *) 0);}
;
classname: UPPERCASEVAR
| CLASS
;
instancevars: /* empty */
| bar instvarlist bar
;
instvarlist: LOWERCASEVAR {addinst($1);}
| instvarlist LOWERCASEVAR {addinst($2);}
| error {expect("instance variable");}
;
methodlist: method
| methodlist MBAR method
{$3->nextmethod = $1; $$ = $3;}
;
method : pattern tempvars statelist op
{deltemps($2); $$ = mkmethod($1, $2, $3);}
;
pattern: keypattern
{$$ = mkkey((struct exprstruct *) 0, $1);}
| binarysym argvariable
{$$ = mkexpr((struct exprstruct *) 0, bincmd, $1, (struct exprstruct *) 0);}
| LOWERCASEVAR
{$$ = mkexpr((struct exprstruct *) 0, uncmd, $1, (struct exprstruct *) 0);}
| error {expect("method pattern");
$$ = mkexpr((struct exprstruct *) 0, uncmd, "", (struct exprstruct *) 0);}
;
keypattern: KEYWORD argvariable
{$$ = mkklist((struct keylist *) 0, $1, (struct exprstruct *) 0);}
| keypattern KEYWORD argvariable
{$$ = mkklist($1, $2, (struct exprstruct *) 0);}
;
argvariable: LOWERCASEVAR {addtemp($1, argvar);}
| error {expect("argument variable");}
;
tempvars: /* empty */ {$$ = 0;}
| bar namelist bar {$$ = $2;}
;
bar : BAR
| MBAR
| error {expect("| (vertical bar)");}
;
namelist: tvariable {$$ = 1;}
| namelist tvariable {$$ = $1 + 1;}
;
tvariable: LOWERCASEVAR {addtemp($1, tempvar);}
;
statelist: statement {$$ = $1;}
| statelist PERIOD statement {$3->nextstate = $1; $$ = $3;}
;
op : /* empty - optional period */
| PERIOD
;
statement: UPARROW sexpression {$$ = mkstate(upar, (char *) 0, $2);}
| sexpression
;
sexpression: LOWERCASEVAR ASSIGN sexpression
{$$ = mkstate(asgn, $1, $3);}
| cexpression
{$$ = mkstate(expr, (char *) 0, (struct statestruct *) $1);}
;
cexpression: expression
| kcontinuation {$$ = mkexpr($1, semiend, 0, 0);}
;
kcontinuation: bcontinuation
| bcontinuation keywordlist {$$ = mkkey($1, $2);}
;
bcontinuation: ucontinuation
| bcontinuation binarysym unary
{$$ = mkexpr($1, bincmd, $2, $3);}
;
ucontinuation: cexpression SEMI {$$ = mkexpr($1, semistart, 0, 0);}
| ucontinuation LOWERCASEVAR
{$$ = mkexpr($1, uncmd, $2, (struct exprstruct *) 0);}
;
expression: binary {$$ = $1;}
| binary keywordlist {$$ = mkkey($1, $2);}
;
keywordlist: KEYWORD binary
{$$ = mkklist((struct keylist *) 0, $1, $2);}
| keywordlist KEYWORD binary
{$$ = mkklist($1, $2, $3);}
;
binary : unary {$$ = $1;}
| binary binarysym unary {$$ = mkexpr($1, bincmd, $2, $3);}
;
binarysym: binarychar {$$ = $1;}
| binarychar binarychar {$$ = bincat($1, $2);}
;
binarychar: BINARY
| BAR
| MINUS
| UPARROW
| PE
;
unary : primary
{$$ = mkexpr((struct exprstruct *) 0, reccmd, (char *) 0,
(struct exprstruct *) $1);}
| unary LOWERCASEVAR
{$$ = mkexpr($1, uncmd, $2, (struct exprstruct *) 0);}
;
primary : classname {e.c = $1; $$ = mkobj(classobj, &e);}
| LOWERCASEVAR {e.c = $1; $$ = mkobj(varobj, &e);}
| literal {e.t = $1; $$ = mkobj(litobj, &e);}
| PSEUDO {e.p = $1; $$ = mkobj(pseuobj, &e);}
| primitive {e.u = $1; $$ = mkobj(primobj, &e);}
| LP sexpression RP {e.s = $2; $$ = mkobj(exprobj, &e);}
| block {e.b = $1; $$ = mkobj(blockobj, &e);}
;
primitive: PRIMITIVE LITNUM objlist PE
{$$ = mkprim($2, $3);}
| NAMEDPRIM objlist PE
{$$ = mkprim($1, $2);}
;
objlist : /* empty */ {$$ = (struct primlist *) 0;}
| objlist primary {$$ = addprim($1, $2);}
;
block : LB barglist opmessagelist RB
{$$ = mkblock($2, $3);
deltemps($2);}
;
barglist : /* empty */ {$$ = 0;}
| cvarlist BAR {$$ = $1;}
;
cvarlist: COLONVAR {addtemp($1, argvar); $$ = 1;}
| cvarlist COLONVAR {addtemp($2, argvar); $$ = $1 + 1;}
;
opmessagelist: bstatelist bstatement {$2->nextstate = $1; $$ = $2;}
| bstatement {$$ = $1;}
;
bstatement: UPARROW sexpression {$$ = mkstate(blkupar, (char *) 0, $2);}
| bexpression {$$ = mkstate(upar, (char *) 0, $1);}
;
bexpression: /* empty */
{e.p = nilvar;
$$ = mkstate(expr, (char *) 0,
(struct statestr