mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-16 09:11:21 +00:00
Lemon update 2016-02-17 01:18:33 on branch parser-performance
- In Lemon, add the ability for the left-most RHS label to be the same as the LHS label, causing the LHS values to be written directly into the stack. (user: drh)
This commit is contained in:
parent
75f6d3a438
commit
8a18e5c7eb
2 changed files with 112 additions and 23 deletions
|
@ -190,6 +190,8 @@ struct rule {
|
||||||
const char **rhsalias; /* An alias for each RHS symbol (NULL if none) */
|
const char **rhsalias; /* An alias for each RHS symbol (NULL if none) */
|
||||||
int line; /* Line number at which code begins */
|
int line; /* Line number at which code begins */
|
||||||
const char *code; /* The code executed when this rule is reduced */
|
const char *code; /* The code executed when this rule is reduced */
|
||||||
|
const char *codePrefix; /* Setup code before code[] above */
|
||||||
|
const char *codeSuffix; /* Breakdown code after code[] above */
|
||||||
struct symbol *precsym; /* Precedence symbol for this rule */
|
struct symbol *precsym; /* Precedence symbol for this rule */
|
||||||
int index; /* An index number for this rule */
|
int index; /* An index number for this rule */
|
||||||
Boolean canReduce; /* True if this rule is ever reduced */
|
Boolean canReduce; /* True if this rule is ever reduced */
|
||||||
|
@ -3365,6 +3367,7 @@ PRIVATE char *append_str(const char *zText, int n, int p1, int p2, int bNoSubst)
|
||||||
int c;
|
int c;
|
||||||
char zInt[40];
|
char zInt[40];
|
||||||
if( zText==0 ){
|
if( zText==0 ){
|
||||||
|
if( used==0 && z!=0 ) z[0] = 0;
|
||||||
used = 0;
|
used = 0;
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
@ -3406,7 +3409,9 @@ PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){
|
||||||
char *cp, *xp;
|
char *cp, *xp;
|
||||||
int i;
|
int i;
|
||||||
char lhsused = 0; /* True if the LHS element has been used */
|
char lhsused = 0; /* True if the LHS element has been used */
|
||||||
|
char lhsdirect; /* True if LHS writes directly into stack */
|
||||||
char used[MAXRHS]; /* True for each RHS element which is used */
|
char used[MAXRHS]; /* True for each RHS element which is used */
|
||||||
|
char zLhs[50]; /* Convert the LHS symbol into this string */
|
||||||
|
|
||||||
for(i=0; i<rp->nrhs; i++) used[i] = 0;
|
for(i=0; i<rp->nrhs; i++) used[i] = 0;
|
||||||
lhsused = 0;
|
lhsused = 0;
|
||||||
|
@ -3417,6 +3422,47 @@ PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){
|
||||||
rp->line = rp->ruleline;
|
rp->line = rp->ruleline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( rp->lhsalias==0 ){
|
||||||
|
/* There is no LHS value symbol. */
|
||||||
|
lhsdirect = 1;
|
||||||
|
}else if( rp->nrhs==0 ){
|
||||||
|
/* If there are no RHS symbols, then writing directly to the LHS is ok */
|
||||||
|
lhsdirect = 1;
|
||||||
|
}else if( rp->rhsalias[0]==0 ){
|
||||||
|
/* The left-most RHS symbol has not value. LHS direct is ok. But
|
||||||
|
** we have to call the distructor on the RHS symbol first. */
|
||||||
|
lhsdirect = 1;
|
||||||
|
if( has_destructor(rp->rhs[0],lemp) ){
|
||||||
|
append_str(0,0,0,0,0);
|
||||||
|
append_str(" yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0,
|
||||||
|
rp->rhs[0]->index,1-rp->nrhs,0);
|
||||||
|
rp->codePrefix = Strsafe(append_str(0,0,0,0,0));
|
||||||
|
}
|
||||||
|
}else if( strcmp(rp->lhsalias,rp->rhsalias[0])==0 ){
|
||||||
|
/* The LHS symbol and the left-most RHS symbol are the same, so
|
||||||
|
** direct writing is allowed */
|
||||||
|
lhsdirect = 1;
|
||||||
|
lhsused = 1;
|
||||||
|
used[0] = 1;
|
||||||
|
if( rp->lhs->dtnum!=rp->rhs[0]->dtnum ){
|
||||||
|
ErrorMsg(lemp->filename,rp->ruleline,
|
||||||
|
"%s(%s) and %s(%s) share the same label but have "
|
||||||
|
"different datatypes.",
|
||||||
|
rp->lhs->name, rp->lhsalias, rp->rhs[0]->name, rp->rhsalias[0]);
|
||||||
|
lemp->errorcnt++;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
lhsdirect = 0;
|
||||||
|
}
|
||||||
|
if( lhsdirect ){
|
||||||
|
sprintf(zLhs, "yymsp[%d].minor.yy%d",1-rp->nrhs,rp->lhs->dtnum);
|
||||||
|
}else{
|
||||||
|
append_str(0,0,0,0,0);
|
||||||
|
append_str(" YYMINORTYPE yylhsminor;\n", 0, 0, 0, 0);
|
||||||
|
rp->codePrefix = Strsafe(append_str(0,0,0,0,0));
|
||||||
|
sprintf(zLhs, "yylhsminor.yy%d",rp->lhs->dtnum);
|
||||||
|
}
|
||||||
|
|
||||||
append_str(0,0,0,0,0);
|
append_str(0,0,0,0,0);
|
||||||
|
|
||||||
/* This const cast is wrong but harmless, if we're careful. */
|
/* This const cast is wrong but harmless, if we're careful. */
|
||||||
|
@ -3427,7 +3473,7 @@ PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){
|
||||||
saved = *xp;
|
saved = *xp;
|
||||||
*xp = 0;
|
*xp = 0;
|
||||||
if( rp->lhsalias && strcmp(cp,rp->lhsalias)==0 ){
|
if( rp->lhsalias && strcmp(cp,rp->lhsalias)==0 ){
|
||||||
append_str("yygotominor.yy%d",0,rp->lhs->dtnum,0,0);
|
append_str(zLhs,0,0,0,0);
|
||||||
cp = xp;
|
cp = xp;
|
||||||
lhsused = 1;
|
lhsused = 1;
|
||||||
}else{
|
}else{
|
||||||
|
@ -3458,6 +3504,11 @@ PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){
|
||||||
append_str(cp, 1, 0, 0, 1);
|
append_str(cp, 1, 0, 0, 1);
|
||||||
} /* End loop */
|
} /* End loop */
|
||||||
|
|
||||||
|
/* Main code generation completed */
|
||||||
|
cp = append_str(0,0,0,0,0);
|
||||||
|
if( cp && cp[0] ) rp->code = Strsafe(cp);
|
||||||
|
append_str(0,0,0,0,0);
|
||||||
|
|
||||||
/* Check to make sure the LHS has been used */
|
/* Check to make sure the LHS has been used */
|
||||||
if( rp->lhsalias && !lhsused ){
|
if( rp->lhsalias && !lhsused ){
|
||||||
ErrorMsg(lemp->filename,rp->ruleline,
|
ErrorMsg(lemp->filename,rp->ruleline,
|
||||||
|
@ -3466,27 +3517,53 @@ PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){
|
||||||
lemp->errorcnt++;
|
lemp->errorcnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate destructor code for RHS symbols which are not used in the
|
/* Generate destructor code for RHS minor values which are not referenced.
|
||||||
** reduce code */
|
** Generate error messages for unused labels and duplicate labels.
|
||||||
|
*/
|
||||||
for(i=0; i<rp->nrhs; i++){
|
for(i=0; i<rp->nrhs; i++){
|
||||||
if( rp->rhsalias[i] && !used[i] ){
|
if( rp->rhsalias[i] ){
|
||||||
ErrorMsg(lemp->filename,rp->ruleline,
|
if( i>0 ){
|
||||||
"Label %s for \"%s(%s)\" is never used.",
|
int j;
|
||||||
rp->rhsalias[i],rp->rhs[i]->name,rp->rhsalias[i]);
|
if( rp->lhsalias && strcmp(rp->lhsalias,rp->rhsalias[i])==0 ){
|
||||||
lemp->errorcnt++;
|
ErrorMsg(lemp->filename,rp->ruleline,
|
||||||
}else if( rp->rhsalias[i]==0 ){
|
"%s(%s) has the same label as the LHS but is not the left-most "
|
||||||
if( has_destructor(rp->rhs[i],lemp) ){
|
"symbol on the RHS.",
|
||||||
append_str(" yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0,
|
rp->rhs[i]->name, rp->rhsalias);
|
||||||
rp->rhs[i]->index,i-rp->nrhs+1,0);
|
lemp->errorcnt++;
|
||||||
}else{
|
}
|
||||||
/* No destructor defined for this term */
|
for(j=0; j<i; j++){
|
||||||
|
if( rp->rhsalias[j] && strcmp(rp->rhsalias[j],rp->rhsalias[i])==0 ){
|
||||||
|
ErrorMsg(lemp->filename,rp->ruleline,
|
||||||
|
"Label %s used for multiple symbols on the RHS of a rule.",
|
||||||
|
rp->rhsalias[i]);
|
||||||
|
lemp->errorcnt++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if( !used[i] ){
|
||||||
|
ErrorMsg(lemp->filename,rp->ruleline,
|
||||||
|
"Label %s for \"%s(%s)\" is never used.",
|
||||||
|
rp->rhsalias[i],rp->rhs[i]->name,rp->rhsalias[i]);
|
||||||
|
lemp->errorcnt++;
|
||||||
|
}
|
||||||
|
}else if( i>0 && has_destructor(rp->rhs[i],lemp) ){
|
||||||
|
append_str(" yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0,
|
||||||
|
rp->rhs[i]->index,i-rp->nrhs+1,0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( rp->code ){
|
|
||||||
cp = append_str(0,0,0,0,0);
|
/* If unable to write LHS values directly into the stack, write the
|
||||||
rp->code = Strsafe(cp?cp:"");
|
** saved LHS value now. */
|
||||||
|
if( lhsdirect==0 ){
|
||||||
|
append_str(" yymsp[%d].minor.yy%d = ", 0, 1-rp->nrhs, rp->lhs->dtnum, 0);
|
||||||
|
append_str(zLhs, 0, 0, 0, 0);
|
||||||
|
append_str(";\n", 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Suffix code generation complete */
|
||||||
|
cp = append_str(0,0,0,0,0);
|
||||||
|
if( cp ) rp->codeSuffix = Strsafe(cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3501,6 +3578,12 @@ PRIVATE void emit_code(
|
||||||
){
|
){
|
||||||
const char *cp;
|
const char *cp;
|
||||||
|
|
||||||
|
/* Setup code prior to the #line directive */
|
||||||
|
if( rp->codePrefix && rp->codePrefix[0] ){
|
||||||
|
fprintf(out, "{%s", rp->codePrefix);
|
||||||
|
for(cp=rp->codePrefix; *cp; cp++){ if( *cp=='\n' ) (*lineno)++; }
|
||||||
|
}
|
||||||
|
|
||||||
/* Generate code to do the reduce action */
|
/* Generate code to do the reduce action */
|
||||||
if( rp->code ){
|
if( rp->code ){
|
||||||
if( !lemp->nolinenosflag ){
|
if( !lemp->nolinenosflag ){
|
||||||
|
@ -3508,15 +3591,23 @@ PRIVATE void emit_code(
|
||||||
tplt_linedir(out,rp->line,lemp->filename);
|
tplt_linedir(out,rp->line,lemp->filename);
|
||||||
}
|
}
|
||||||
fprintf(out,"{%s",rp->code);
|
fprintf(out,"{%s",rp->code);
|
||||||
for(cp=rp->code; *cp; cp++){
|
for(cp=rp->code; *cp; cp++){ if( *cp=='\n' ) (*lineno)++; }
|
||||||
if( *cp=='\n' ) (*lineno)++;
|
|
||||||
} /* End loop */
|
|
||||||
fprintf(out,"}\n"); (*lineno)++;
|
fprintf(out,"}\n"); (*lineno)++;
|
||||||
if( !lemp->nolinenosflag ){
|
if( !lemp->nolinenosflag ){
|
||||||
(*lineno)++;
|
(*lineno)++;
|
||||||
tplt_linedir(out,*lineno,lemp->outname);
|
tplt_linedir(out,*lineno,lemp->outname);
|
||||||
}
|
}
|
||||||
} /* End if( rp->code ) */
|
}
|
||||||
|
|
||||||
|
/* Generate breakdown code that occurs after the #line directive */
|
||||||
|
if( rp->codeSuffix && rp->codeSuffix[0] ){
|
||||||
|
fprintf(out, "%s", rp->codeSuffix);
|
||||||
|
for(cp=rp->codeSuffix; *cp; cp++){ if( *cp=='\n' ) (*lineno)++; }
|
||||||
|
}
|
||||||
|
|
||||||
|
if( rp->codePrefix ){
|
||||||
|
fprintf(out, "}\n"); (*lineno)++;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -623,7 +623,6 @@ static void yy_reduce(
|
||||||
){
|
){
|
||||||
int yygoto; /* The next state */
|
int yygoto; /* The next state */
|
||||||
int yyact; /* The next action */
|
int yyact; /* The next action */
|
||||||
YYMINORTYPE yygotominor; /* The LHS of the rule reduced */
|
|
||||||
yyStackEntry *yymsp; /* The top of the parser's stack */
|
yyStackEntry *yymsp; /* The top of the parser's stack */
|
||||||
int yysize; /* Amount to pop the stack */
|
int yysize; /* Amount to pop the stack */
|
||||||
ParseARG_FETCH;
|
ParseARG_FETCH;
|
||||||
|
@ -687,7 +686,6 @@ static void yy_reduce(
|
||||||
yymsp -= yysize-1;
|
yymsp -= yysize-1;
|
||||||
yymsp->stateno = (YYACTIONTYPE)yyact;
|
yymsp->stateno = (YYACTIONTYPE)yyact;
|
||||||
yymsp->major = (YYCODETYPE)yygoto;
|
yymsp->major = (YYCODETYPE)yygoto;
|
||||||
yymsp->minor = yygotominor;
|
|
||||||
yyTraceShift(yypParser, yyact);
|
yyTraceShift(yypParser, yyact);
|
||||||
}else{
|
}else{
|
||||||
assert( yyact == YY_ACCEPT_ACTION );
|
assert( yyact == YY_ACCEPT_ACTION );
|
||||||
|
|
Loading…
Reference in a new issue