Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
1408 lines (822 sloc) 23.2 KB
/* $Id: langparser.y 1180 2006-04-01 16:11:40Z andreradke $ */
/******************************************************************************
UserLand Frontier(tm) -- High performance Web content management,
object database, system-level and Internet scripting environment,
including source code editing and debugging.
Copyright (C) 1992-2004 UserLand Software, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
******************************************************************************/
%{
/*
langparser.y generates langparser.c.
use MPW Shell and the MPW tool MacYACC to create a LSC-compatible parser
in langparser.c. the command line to generate langparser.c and yytab.h is:
macyacc -d "langparser.y"
*/
/*
these declarations make it possible to compile and run langparser.m
with no modification to the source code as generated by Bison.
*/
#import "Compiler.h"
/*
10/2/91 dmb: a disturbing discovery -- our error handling doesn't deallocate
any of the code tree that's been built so for. searching through langparser.c,
it appears that there are three data structures will need to go through: yyval,
yylval, and the value stack, yyv. Unfortunately, the value stack pointer, yypv,
is a local in yyparse, so we have to be tricky to get at it. so I'm replacing
the yyerror routine with a macro that calls the real error routine, but passes
the stack pointer as an additional parameter.
there's probably a much cleaner way to do this, but I don't have the
documentation, nor much time...
11/22/91 dmb: well, there's little time indeed, but we now have MacYACC 3.0, and
a little documentation. The right was to deal with data structure disposal on
errors is to make sure that there are reduction rules for every error situation,
so that after yyerror is called the parser can ruduce the stack all the way down
to our start token (module), where the tree can be safely disposed. I've added a
number of such reductions that should cover many error situations, but a much more
thorough job needs to be done eventually. It's hard to trap errors at a very atomic
level without introducing ambiguities to the grammer (i.e. reduction conflicts).
So, given the time to work on it, I would go through the definition of "statement"
and add rules for every permutation of errors within the more complex contructs. The
key thing to understand is that "expr" is written to handle any error, so anything
that depends on expr is covered. It's unique contructs associated with some compound
statements that need extra work.
4/30/17: Automatic reference counting means barely worrying about memory disposal at all.
The memory graph debugger will tell us if there are any problems.
*/
%}
%pure-parser
%locations
%defines
%error-verbose
//%union { __unsafe_unretained CodeTreeNode *node; }
%token EQtoken 400 /*must agree with numbers in langtokens.h*/
%token NEtoken 401
%token GTtoken 402
%token LTtoken 403
%token GEtoken 404
%token LEtoken 405
%token nottoken 406
%token andandtoken 407
%token orortoken 408
%token beginswithtoken 409
%token endswithtoken 410
%token containstoken 411
%token bitandtoken 412
%token bitortoken 413
%token looptoken 500 /*must agree with numbers in langtokens.h*/
%token filelooptoken 501
%token intoken 502
%token breaktoken 503
%token returntoken 504
%token iftoken 505
%token thentoken 506
%token elsetoken 507
%token bundletoken 508
%token localtoken 509
%token ontoken 510
%token whiletoken 511
%token casetoken 512
%token kerneltoken 513
%token fortoken 514
%token totoken 515
%token downtotoken 516
%token continuetoken 517
%token withtoken 518
%token trytoken 519
%token globaltoken 520
%token errortoken
%token eoltoken
%token constanttoken
%token identifiertoken
%token othertoken
%token assigntoken
%token addtoken
%token subtracttoken
%token multiplytoken
%token dividetoken
%token modtoken
%token plusplustoken
%token minusminustoken
%left ','
%left assigntoken
%left orortoken
%left andandtoken
%left EQtoken NEtoken
%left LTtoken GTtoken LEtoken GEtoken beginswithtoken endswithtoken containstoken
%left addtoken subtracttoken
%left multiplytoken dividetoken modtoken
%right nottoken
%right plusplustoken minusminustoken unaryminus '@'
%left '^'
%left '.'
%start module /*this is our goal*/
%%
module:
statementlist eoltoken {
yytrace ("module | statementlist eoltoken");
if (pcyyerrct) {
$$ = $1;
return (1);
}
$$ = pushbinaryoperation(moduleop, $1, nil);
return 0;
}
| error {
yytrace ("module | error");
return 1;
}
;
bracketedidentifier:
identifiertoken {
yytrace ("bracketedidentifier : identifiertoken");
$$ = $1;
}
| '[' expr ']' {
yytrace ("bracketedidentifier | '[' expr ']'");
$$ = pushunaryoperation(bracketOp, $2);
}
;
handlerheader:
ontoken bracketedidentifier '(' namelist ')' {
yytrace ("handlerheader | ontoken bracketedidentifier '(' namelist ')'");
$$ = pushbinaryoperation(procop, $2, $4);
}
| ontoken bracketedidentifier '(' ')' {
yytrace ("handlerheader | ontoken bracketedidentifier '(' ')'");
$$ = pushbinaryoperation(procop, $2, nil);
}
/*
| ontoken error {
$$ = nil;
}
*/
;
optionalinit:
/*emptiness*/ {
yytrace ("optionalinit | empty");
$$ = nil;
}
| assigntoken expr {
yytrace ("optionalinit | assigntoken expr");
$$ = $2;
}
| error {
yytrace ("optionalinit | error");
$$ = nil;
}
;
namelistid:
bracketedidentifier optionalinit {
yytrace ("namelistid | optionalinit");
if ($2 == nil)
$$ = $1; /*just return the id*/
else {
$$ = pushbinaryoperation(assignlocalop, $1, $2);
}
}
| error {
yytrace ("namelistid | error");
$$ = nil;
}
;
namelist:
namelistid {
yytrace ("namelist | namelistid");
$$ = $1; /*start the name list off with our address*/
}
| namelist ',' namelistid {
yytrace ("namelist | namelist ',' namelistid");
pushlastlink($3, $1); /*add new name to end of list*/
}
| namelist ';' namelistid {
yytrace ("namelist | namelist ';' namelistid");
pushlastlink($3, $1); /*add new name to end of list*/
}
;
statementlist:
statement {
yytrace ("statementlist: statement");
$$ = $1; /*start the statement list off with our address*/
}
| statementlist ';' statement {
yytrace ("statementlist | statementlist ';' statement");
pushlastlink($3, $1); /*add new statement to end of list*/
$$ = $1;
}
;
bracketedstatementlist:
'{' statementlist '}' {
yytrace ("bracketedstatementlist: '{' statementlist '}'");
$$ = $2;
}
| error {
yytrace ("bracketedstatementlist | error");
$$ = nil;
}
;
derefid:
term '^' {
yytrace ("derefid : term '^'");
$$ = pushunaryoperation(dereferenceop, $1);
}
| functionref '^' {
yytrace ("derefid | functionref '^'");
$$ = pushunaryoperation(dereferenceop, $1);
}
| '(' expr ')' '^' {
yytrace ("derefid | '(' expr ')' '^'");
$$ = pushunaryoperation (dereferenceop, $2);
}
;
dottedid:
term '.' bracketedidentifier {
yytrace ("dottedid : term '.' bracketedidentifier");
$$ = pushbinaryoperation(dotOp, $1, $3);
}
| term '.' error {
yytrace ("dottedid : term '.' error");
$$ = $1;
}
;
rangeref:
expr totoken expr {
yytrace ("rangeref: expr totoken expr");
$$ = pushbinaryoperation(rangeOp, $1, $3);
}
;
arrayref:
term '[' expr ']' {
yytrace ("arrayref: term '[' expr ']'");
$$ = pushbinaryoperation(arrayop, $1, $3);
}
| term '[' rangeref ']' {
yytrace ("arrayref | term '[' rangeref ']'");
$$ = pushbinaryoperation(arrayop, $1, $3);
}
| term '[' fieldspec ']' {
yytrace ("arrayref | term '[' fieldspec ']'");
$$ = pushbinaryoperation(arrayop, $1, $3);
}
;
term:
dottedid {
yytrace ("term: dottedid");
$$ = $1;
}
| arrayref {
yytrace ("term | arrayref");
$$ = $1;
}
| bracketedidentifier {
yytrace ("term | bracketedidentifier");
$$ = $1;
}
| derefid {
yytrace ("term | derefid");
$$ = $1;
}
;
statement:
/*emptiness*/ {
yytrace ("statement: <empty statement>");
$$ = pushoperation(noop); /*a place for the debugger to stop*/
}
| expr {
yytrace ("statement: expr");
$$ = $1;
}
| term assigntoken expr {
yytrace ("statement | term assigntoken expr");
$$ = pushbinaryoperation(assignop, $1, $3);
}
| handlerheader bracketedstatementlist {
yytrace ("statement : handlerheader bracketedstatementlist");
$$ = pushbinaryoperation(moduleop, $2, $1);
}
| handlerheader '{' kernelcall '}' {
yytrace ("statement : handlerheader '{' kernelcall '}'");
$$ = pushbinaryoperation(moduleop, $3, $1);
}
| localtoken '(' namelist ')' {
yytrace ("statement | localtoken '(' namelist ')'");
$$ = pushunaryoperation(localop, $3);
}
| localtoken '{' namelist '}' {
yytrace ("statement | localtoken '{' namelist '}'");
$$ = pushunaryoperation(localop, $3);
}
| globaltoken '(' namelist ')' {
yytrace ("statement | globaltoken '(' namelist ')'");
$$ = pushunaryoperation (globalop, $3);
}
| globaltoken '{' namelist '}' {
yytrace ("statement | globaltoken '{' namelist '}'");
$$ = pushunaryoperation(globalop, $3);
}
| fileloopheader bracketedstatementlist {
yytrace ("statement | fileloopheader bracketedstatementlist");
pushtripletstatementlists(nil, $2, $1);
$$ = $1;
}
| loopheader bracketedstatementlist {
yytrace ("statement | loopheader bracketedstatementlist");
pushloopbody($2, $1);
$$ = $1;
}
| forloopheader bracketedstatementlist {
yytrace ("statement | forloopheader bracketedstatementlist");
pushloopbody($2, $1);
$$ = $1;
}
| forinloopheader bracketedstatementlist {
yytrace ("statement | forinloopheader bracketedstatementlist");
pushloopbody($2, $1);
$$ = $1;
}
| ifheader bracketedstatementlist {
yytrace ("statement | ifheader bracketedstatementlist");
pushtripletstatementlists($2, nil, $1);
$$ = $1;
}
| ifheader bracketedstatementlist elsetoken bracketedstatementlist {
yytrace ("statement | ifheader bracketedstatementlist elsetoken bracketedstatementlist");
pushtripletstatementlists($2, $4, $1);
$$ = $1;
}
| bundleheader bracketedstatementlist {
yytrace ("statement | bundleheader bracketedstatementlist");
pushunarystatementlist($2, $1);
$$ = $1;
}
| breaktoken '(' ')' {
yytrace ("statement | breaktoken '(' ')'");
$$ = pushoperation(breakop);
}
| breaktoken {
yytrace ("statement | breaktoken");
$$ = pushoperation(breakop);
}
| continuetoken {
yytrace ("statement | continuetoken");
$$ = pushoperation(continueop);
}
| returntoken optionalexpr {
yytrace ("statement | returntoken");
$$ = pushunaryoperation(returnop, $2);
}
| caseheader '{' casebody '}' {
yytrace ("statement | caseheader casebody");
pushtripletstatementlists($3, nil, $1);
$$ = $1;
}
| caseheader '{' casebody '}' elsetoken bracketedstatementlist {
yytrace ("statement | caseheader casebody elsetoken bracketedstatementlist");
pushtripletstatementlists($3, $6, $1);
$$ = $1;
}
| withheader bracketedstatementlist {
yytrace ("statement | withheader bracketedstatementlist");
pushtripletstatementlists($2, nil, $1);
$$ = $1;
}
| tryheader bracketedstatementlist {
yytrace ("statement | tryheader bracketedstatementlist");
pushtripletstatementlists($2, nil, $1);
$$ = $1;
}
| tryheader bracketedstatementlist elsetoken bracketedstatementlist {
yytrace ("statement | tryheader bracketedstatementlist elsetoken bracketedstatementlist");
pushtripletstatementlists($2, $4, $1);
$$ = $1;
}
| expr error {
yytrace ("statement | expr error");
$$ = $1;
}
/*
| expr error expr {
if (!pushbinaryoperation (noop, $1, $3, &$$))
goto cleanexit;
}
*/
;
kernelcall:
kerneltoken '(' dottedid ')' {
yytrace ("kernelcall: kerneltoken '(' dottedid ')'");
$$ = pushkernelcall($3);
}
;
/*
fileloopspec:
expr {
yytrace ("fileloopspec: expr");
$$ = $1;
}
| constanttoken '[' expr ']' {
yytrace ("fileloopspec | constanttoken '[' expr ']'");
if (!pushbinaryoperation (arrayop, $1, $3, &$$))
goto cleanexit;
}
;
*/
fileloopheader:
filelooptoken '(' bracketedidentifier intoken expr ')' {
yytrace ("fileloopheader: filelooptoken '(' bracketedidentifier intoken expr ')'");
$$ = pushquadruplet(fileloopop, $3, $5, nil, nil);
}
| filelooptoken '(' bracketedidentifier intoken expr ',' expr ')' {
yytrace ("fileloopheader | filelooptoken '(' bracketedidentifier intoken expr ',' expr ')'");
$$ = pushquadruplet(fileloopop, $3, $5, nil, $7);
}
| filelooptoken '(' bracketedidentifier error {
yytrace ("fileloopheader | filelooptoken '(' bracketedidentifier error");
$$ = pushquadruplet(fileloopop, $3, nil, nil, nil);
}
;
loopheader:
looptoken '(' statement ';' expr ';' statement ')' {
yytrace ("loopheader: looptoken '(' statement ';' expr ';' statement ')'");
$$ = pushloop($3, $5, $7);
goto cleanexit;
}
| looptoken {
yytrace ("loopheader | looptoken");
$$ = pushloop(nil, nil, nil);
}
| looptoken '(' expr ')' {
yytrace ("loopheader | looptoken '(' expr ')'");
$$ = pushloop($3, nil, nil);
}
| whiletoken expr {
yytrace ("loopheader | whiletoken expr");
$$ = pushloop(nil, $2, nil);
}
| looptoken '(' statement ';' expr ')' {
yytrace ("loopheader | looptoken '(' statement ';' expr ')'");
$$ = pushloop($3, $5, nil);
}
;
forloopheader:
fortoken term assigntoken expr totoken expr {
yytrace ("forloopheader: fortoken term assigntoken expr totoken expr");
$$ = pushquadruplet(forloopop, $4, $6, $2, nil);
}
| fortoken '(' term assigntoken expr totoken expr ')' {
yytrace ("forloopheader | fortoken '(' term assigntoken expr totoken expr ')' ");
$$ = pushquadruplet(forloopop, $5, $7, $3, nil);
}
| fortoken term assigntoken expr downtotoken expr {
yytrace ("forloopheader | fortoken term assigntoken expr downtotoken expr");
$$ = pushquadruplet(fordownloopop, $4, $6, $2, nil);
}
| fortoken '(' term assigntoken expr downtotoken expr ')' {
yytrace ("forloopheader | fortoken '(' term assigntoken expr downtotoken expr ')' ");
$$ = pushquadruplet(fordownloopop, $5, $7, $3, nil);
}
| fortoken term assigntoken expr error {
yytrace ("forloopheader: fortoken term assigntoken expr error");
$$ = pushquadruplet(noop, $2, $4, nil, nil);
}
| fortoken term error {
yytrace ("forloopheader: fortoken term error");
$$ = pushquadruplet(noop, $2, nil, nil, nil);
}
;
forinloopheader:
fortoken term intoken expr {
yytrace ("forinloopheader: fortoken term intoken expr");
$$ = pushquadruplet(forinloopop, $4, $2, nil, nil);
}
| fortoken '(' term intoken expr ')' {
yytrace ("forinloopheader | fortoken '(' term intoken expr ')' ");
$$ = pushquadruplet(forinloopop, $5, $3, nil, nil);
}
;
ifheader:
iftoken expr {
yytrace ("ifheader: iftoken expr");
$$ = pushtriplet(ifop, $2, nil, nil);
}
;
tryheader:
trytoken {
yytrace ("tryheader | trytoken");
$$ = pushtriplet (tryop, nil, nil, nil); /*it's really just a binary*/
}
;
bundleheader:
bundletoken {
yytrace ("bundleheader: bundletoken");
$$ = pushunaryoperation(bundleop, nil);
}
;
caseheader:
casetoken expr {
yytrace ("caseheader | casetoken expr");
$$ = pushtriplet(caseop, $2, nil, nil);
}
;
optionalstatementlist:
/*emptiness*/ {
yytrace ("optionalstatementlist : (empty list)");
$$ = nil;
}
| bracketedstatementlist {
yytrace ("optionalstatementlist | bracketedstatementlist");
$$ = $1;
}
;
casebody:
expr optionalstatementlist {
yytrace ("casebody: expr optionalstatementlist");
$$ = pushbinaryoperation(casebodyop, $1, $2);
}
| casebody ';' expr optionalstatementlist {
yytrace ("casebody | casebody ';' expr optionalstatementlist");
$$ = pushbinaryoperation(casebodyop, $3, $4);
pushlastlink($$, $1);
$$ = $1;
}
;
withheader:
withtoken termlist {
yytrace ("withheader: withtoken termlist");
$$ = pushbinaryoperation(withop, $2, nil);
}
;
termlist:
term {
yytrace ("termlist: term");
$$ = $1;
}
| termlist ',' term {
yytrace ("termlist | termlist ',' term");
pushlastlink($3, $1);
$$ = $1;
}
;
exprlist:
expr {
yytrace ("exprlist: expr");
$$ = $1;
}
| exprlist ',' expr {
yytrace ("exprlist | exprlist ',' expr");
pushlastlink($3, $1);
$$ = $1;
}
;
optionalexprlist:
/*emptiness*/ {
yytrace ("optionalexprlist : (empty list)");
$$ = nil;
}
| exprlist {
yytrace ("optionalexprlist | exprlist");
$$ = $1;
}
;
/*for optional parameters
optionalexprlist:
optionalexpr {
yytrace ("optionalexprlist: optionalexpr");
$$ = $1;
}
| optionalexprlist ',' optionalexpr {
yytrace ("optionalexprlist | optionalexprlist ',' optionalexpr");
if (!pushlastoptionallink ($3, $1, &$$))
goto cleanexit;
}
;
*/
optionalexpr:
/*emptiness*/ {
yytrace ("optionalexpr : (empty expr)");
$$ = nil;
}
| expr {
yytrace ("optionalexpr | expr");
$$ = $1;
}
;
fieldspec:
expr ':' expr {
yytrace ("fieldspec: expr : expr ");
$$ = pushbinaryoperation(fieldop, $1, $3);
}
;
fieldlist:
fieldspec {
yytrace ("fieldlist: fieldspec ");
$$ = $1;
}
| fieldlist ',' fieldspec {
yytrace ("fieldlist | fieldlist ',' fieldspec");
pushlastlink($3, $1);
$$ = $1;
}
;
namedvalue:
bracketedidentifier ':' expr {
yytrace ("namedvalue: bracketedidentifier : expr ");
$$ = pushbinaryoperation(fieldop, $1, $3);
}
;
namedvaluelist:
namedvalue {
yytrace ("namedvaluelist: namedvalue ");
$$ = $1;
}
| namedvaluelist ',' namedvalue {
yytrace ("namedvaluelist | namedvaluelist ',' namedvalue");
pushlastlink($3, $1);
$$ = $1;
}
;
parameterlist:
optionalexprlist {
yytrace ("parameterlist : optionalexprlist");
$$ = $1;
}
| namedvaluelist {
yytrace ("parameterlist | namedvaluelist");
$$ = $1;
}
| exprlist ',' namedvaluelist {
yytrace ("parameterlist | exprlist ',' namedvaluelist");
pushlastlink($3, $1);
$$ = $1;
}
;
functionref:
term '(' parameterlist ')' {
yytrace ("functionref: term '(' parameterlist ')'");
pushfunctioncall($1, $3, &$$);
}
;
expr:
constanttoken {
yytrace ("expr | constanttoken");
$$ = $1;
}
| term {
yytrace ("expr | term");
$$ = $1;
}
| '@' term {
yytrace ("expr | '@' term");
$$ = pushunaryoperation(addressofop, $2);
}
| functionref {
yytrace ("expr | functionref");
$$ = $1;
}
| plusplustoken term {
yytrace ("expr | plusplustoken term");
$$ = pushunaryoperation(incrpreop, $2);
}
| term plusplustoken {
yytrace ("expr | term plusplustoken");
$$ = pushunaryoperation(incrpostop, $1);
}
| minusminustoken term {
yytrace ("expr | minusminustoken term");
$$ = pushunaryoperation(decrpreop, $2);
}
| term minusminustoken {
yytrace ("expr | term minusminustoken");
$$ = pushunaryoperation(decrpostop, $1);
}
| '(' expr ')' {
yytrace ("expr | '(' expr ')'");
$$ = $2;
}
| expr addtoken expr {
yytrace ("expr | expr addtoken expr");
$$ = pushbinaryoperation(addop, $1, $3);
}
| expr subtracttoken expr {
yytrace ("expr | expr subtracttoken expr");
$$ = pushbinaryoperation(subtractop, $1, $3);
}
| expr multiplytoken expr {
yytrace ("expr | expr multiplytoken expr");
$$ = pushbinaryoperation(multiplyop, $1, $3);
}
| expr dividetoken expr {
yytrace ("expr | expr dividetoken expr");
$$ = pushbinaryoperation(divideop, $1, $3);
}
| expr modtoken expr {
yytrace ("expr | expr modtoken expr");
$$ = pushbinaryoperation(modop, $1, $3);
}
| expr EQtoken expr {
yytrace ("expr | expr EQtoken expr");
$$ = pushbinaryoperation(EQop, $1, $3);
}
| expr NEtoken expr {
yytrace ("expr | expr NEtoken expr");
$$ = pushbinaryoperation(NEop, $1, $3);
}
| expr LTtoken expr {
yytrace ("expr | expr LTtoken expr");
$$ = pushbinaryoperation(LTop, $1, $3);
}
| expr LEtoken expr {
yytrace ("expr | expr LEtoken expr");
$$ = pushbinaryoperation(LEop, $1, $3);
}
| expr GTtoken expr {
yytrace ("expr | expr GTtoken expr");
$$ = pushbinaryoperation(GTop, $1, $3);
}
| expr GEtoken expr {
yytrace ("expr | expr GEtoken expr");
$$ = pushbinaryoperation(GEop, $1, $3);
}
| expr beginswithtoken expr {
yytrace ("expr | expr beginswithtoken expr");
$$ = pushbinaryoperation(beginswithop, $1, $3);
}
| expr endswithtoken expr {
yytrace ("expr | expr endswithtoken expr");
$$ = pushbinaryoperation(endswithop, $1, $3);
}
| expr containstoken expr {
yytrace ("expr | expr containstoken expr");
$$ = pushbinaryoperation(containsop, $1, $3);
}
| expr orortoken expr {
yytrace ("expr | expr orortoken expr");
$$ = pushbinaryoperation(ororop, $1, $3);
}
| expr andandtoken expr {
yytrace ("expr | expr andandtoken expr");
$$ = pushbinaryoperation(andandop, $1, $3);
}
| subtracttoken expr %prec unaryminus {
yytrace ("expr | subtracttoken expr %prec unaryminus");
$$ = pushunaryoperation(unaryop, $2);
}
| nottoken expr {
yytrace ("expr | nottoken expr");
$$ = pushunaryoperation(notop, $2);
}
| '{' optionalexprlist '}' {
yytrace ("expr | '{' exprlist '}'");
$$ = pushunaryoperation(listop, $2);
}
| '{' fieldlist '}' {
yytrace ("expr | '{' fieldlist '}'");
$$ = pushunaryoperation(recordop, $2);
}
/*
| error {
yytrace ("expr | error");
$$ = $1;
}
*/
;
%%
#ifdef fldebug
#define yytrace(s)
// static void yytrace (char * s) { //TODO
//
// bigstring bs;
//
// copyctopstring (s, bs);
//
// langtrace (bs);
// } /*yytrace*/
#else
#define yytrace(s)
#endif
static int yylex (void) {
/*
get the next token from the input stream. return the token number, and
set the global yylval to the value of the token, if it has one.
*/
return (parsegettoken (&yylval));
} /*yylex*/
static void yyerror (char *s) {
/*
langdisposetree (yyval);
langdisposetree (yylval);
*/
/*
clearbytes (&parseresult, (long) sizeof (parseresult));
*/
parseerror ((ptrstring) s); //TODO
} /*yyerror*/