📄 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 + -