📄 grammar.y
字号:
* ---------------------- */quantity: NUMBER { $$ = Code(Push_Dimensionless); Code3(Push_Constant, (Inst)$1, Dimension_Eval); } | NUMBER dimensions { Code3(Push_Constant, (Inst)$1, Dimension_Eval); $$ = $2;} | VAR { $$ = Code3(Push_Variable, (Inst)$1, Variable_Eval); } | BLTIN_QUANTITY '(' ')' { Code2( Bltin_Quantity, (Inst)$1->u.quantityptr); } | BLTIN1_QUANTITY '(' quantity ')' { Code2( Bltin1_Quantity, (Inst)$1->u.quantityptr); } | BLTIN2_QUANTITY '(' quantity ',' quantity ')' { Code2( Bltin2_Quantity, (Inst)$1->u.quantityptr); } | BLTIN3_QUANTITY '(' matrix ')' { Code2( Bltin3_Quantity, (Inst)$1->u.quantityptr); } | BLTINVar_QUANTITY '('quantity_row ')' { Code2(Push_Variable, (Inst)$3); $$ = Code2(BltinVar_Quantity, (Inst)$1->u.quantityptr); } | '-' quantity %prec UNARYMINUS { Code(Quantity_Negate); } | '+' quantity %prec UNARYPLUS { Code(Quantity_Affirm); } | m_to_quantity { $$ = $1; } | quantity_assign { ;} | conditional_quantity { $$ = $1;} | '(' quantity ')' { $$ = $2; } | quantity '+' quantity { Code(Quantity_Add); } | quantity '-' quantity { Code(Quantity_Sub); } | quantity '*' quantity { Code(Quantity_Mul); } | quantity '/' quantity { Code(Quantity_Div); } | quantity '^' quantity { Code(Quantity_Power); } ;conditional_quantity: quantity GT quantity { Code(Quantity_Gt); } | quantity GE quantity { Code(Quantity_Ge); } | quantity LT quantity { Code(Quantity_Lt); } | quantity LE quantity { Code(Quantity_Le); } | quantity EQ quantity { Code(Quantity_Eq); } | quantity NE quantity { Code(Quantity_Ne); } | quantity AND quantity { Code(Quantity_And); } | quantity OR quantity { Code(Quantity_Or); } | NOT quantity { Code(Quantity_Not); $$ = $2; } ; quantity_assign : VAR '=' quantity { Code2( Push_Variable, (Inst)$1); Code( Assign_Quantity); $$ = $3; } | MATX '[' quantity ']' '[' quantity ']' '=' quantity { Code2( Push_Matrix, (Inst)$1); Code( Assign_Matrix_Item ); $$ = $9;} ; m_to_quantity : MATX '[' quantity ']' '[' quantity ']' { Code3( Push_Matrix, (Inst)$1, Matrix_Eval); Code( Quantity_Extract); } ;dimensions: DIMENSION { $$ = Code2( Push_Dimension, (Inst)$1); } | '(' dimensions ')' { $$ = $2; } | dimensions '*' dimensions { Code( Dimension_Mult ); } | dimensions '/' dimensions { Code( Dimension_Div); } | dimensions '^' quantity { $$ = $1; Code( Dimension_Power); } ; %%/* * ------------------------------ * Lexical Analysis * ------------------------------ */#include <stdio.h> #include <ctype.h> #include <signal.h>#include <setjmp.h>char *progname;extern int lineno;extern char *infile;extern FILE *fin;extern FILE *finp;extern jmp_buf begin;int indef, c;int backslash();int follow();int yyerror();void warning();void EXECUTION_ERROR();void fpecatch();void Defn_Only();yylex(){int finished; /* [a] : Eat blank space, tab, and newline input -- read comment statements */ while((c = fgetc(fin)) == ' ' || c == '\t' || c == '\n' || c == '/') { if(c == '\n') lineno++; if(fin == stdin && finp != stdin) { if(c == '\n') { printf("ALADDIN : "); fflush(stdout); } fputc(c, finp); } if(c == '/') { if(follow('*', TRUE, FALSE) == TRUE) { c = fgetc(fin); finished = FALSE; while(finished == FALSE) { c = fgetc(fin); if(c == '\n') lineno++; if(c == EOF) FatalError("ERROR >> ... file ended with unbalanced comment !!\n", (char *)NULL); if((c == '*') && (follow('/', TRUE, FALSE) == TRUE)) { finished = TRUE; } } } else { return c; } } } /* [b] : return end-of-file */ if(c == EOF) { return END_OF_FILE; } /* [c] : read and store floating-point numbers */ if (c == '.' || isdigit(c)) { double value; ungetc(c, fin); fscanf(fin, "%lf", &value); if(fin == stdin && finp != stdin) fprintf(finp, "%lf", value); yylval.sym = build_table("", NUMBER, value); return NUMBER; } /* [d] : read and store variable */ if (isalpha(c) || c == '_') { SYMBOL *s; char sbuf[100], *p = sbuf; do { if(p >= sbuf + sizeof(sbuf) - 1) { p = '\0'; EXECUTION_ERROR("ERROR >> name too long"); } *p++ = c; } while ((( c = fgetc(fin)) != EOF) && (isalnum(c) || (c == '_' ))); ungetc(c, fin); *p = '\0'; if(fin == stdin && finp != stdin) fprintf(finp, "%s", sbuf); if ((s = lookup(sbuf)) == 0) { s = build_table(sbuf, VAR, 0.0); } yylval.sym = s; switch((int) s->type) { case UNDEF: case VAR: case QUAN: return VAR; default: return (s->type); } } /* [e] : Get Quoted String */ if (c == '"') { char sbuf[100], *p; if(fin == stdin && finp != stdin) fputc(c, finp); for(p = sbuf; (c = fgetc(fin)) != '"'; p++) { if(c == '\n' || c == EOF) EXECUTION_ERROR("ERROR >> missing quote"); if(p >= sbuf + sizeof(sbuf) - 1) { p = '\0'; EXECUTION_ERROR("ERROR >> string name too long"); } if((fin == stdin && finp != stdin)) fputc(c, finp); *p = backslash(c); } *p = 0; yylval.sym = (SYMBOL *) SaveString(sbuf); if(fin == stdin && finp != stdin) fputc(c, finp); return STRING; } if(fin == stdin && finp != stdin) { fputc(c, finp); } switch(c) { case '>': return follow('=', GE, GT); case '<': return follow('=', LE, LT); case '=': return follow('=', EQ, '='); case '!': return follow('=', NE, NOT); case '|': return follow('|', OR, '|'); case '&': return follow('&', AND, '&'); case '\n': lineno = lineno + 1; return '\n'; default: return c; }}/* Error Traceback Routines */int yyerror(s)char *s;{ warning(s, (char *) 0);}int backslash(c)int c;{char *index();static char transtab[] = "b\bf\fn\nr\rt\t"; if(c != '\\') return c; c = fgetc(fin); if(fin == stdin && finp != stdin) fputc(c, finp); if(islower(c) && index(transtab, c)) return index(transtab, c)[1]; return c;}int follow(expect, ifyes, ifno)int expect, ifyes, ifno;{int c = fgetc(fin); if(c == expect) { if(fin == stdin && finp != stdin && ( c != '*' && c != '/') ) fputc(c, finp); return ifyes; } ungetc(c, fin); return ifno;}void Defn_Only(s)char *s;{ if(!indef) EXECUTION_ERROR("ERROR >> Variable used outside definition", (char *) 0);}void fpecatch(){ EXECUTION_ERROR("Floating point exception", (char *) 0);}void EXECUTION_ERROR(s, t)char *s, *t;{ warning(s, t); fseek(fin,0L,2); longjmp(begin,0);}void warning(s, t)char *s, *t;{ fprintf(stderr, "%s: %s", progname, s); if(t) fprintf(stderr,"ERROR >> %s",t); if(infile) fprintf(stderr," in file '%s' ",infile); fprintf(stderr,"near line %d\n",lineno); FatalError("In Warning()",(char *)NULL); /* flush rest on file input */ while(c == '\n' && c != EOF) c = fgetc(fin); if(c == '\n') lineno = lineno + 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -