| The lab5 repo has been updated (as of 1:08 Monday) to include the lab4 sample solution as a baseline, with fixes for the language change and preliminary code for the symbol table/functions and token/nonterminal storage |
|
LANGUAGE MODIFICATION: variable types must now be specified when we declare
our variable, either as a number or a string.
The var keyword for declarations is replaced by two type-specific versions: numvar and strvar, to declare numeric variables and string variables respectively. The isnum and isstr operations are now obsolete and removed from the language. |
/* info struct for tokens and non-terminals:
* row,col: the row/column of the relevant token in the source code
* content: the actual text content of the token
* type: 0 for numeric, 1 for text, -1 if unknown or invalid
*/
%union { struct itemInfo { char content[128]; int row; int col; int type; } info; }
/* identify the valid token types, all have yylval type long */
%token <struct itemInfo> ASSIGN PLUS MINUS TIMES DIV POW LEFTBR RIGHTBR LEFTPAR RIGHTPAR
%token <struct itemInfo> LT GT LE GE EQ NE NUMDEF STRDEF IDENT STRLIT NUMLIT IF ELSE WHILE READ PRINT
%type <struct itemInfo> program statements statement vardecl assignment expr value mathop
%type <struct itemInfo> inputstmt outputstmt whileloop ifelse condition compop
|
["][^"\n]*["] { col+=strlen(yytext);
yylval.info.row = row;
yylval.info.col = col;
strncpy(yylval.info.content, yytext, 128);
yylval.info.type = 1;
return(STRLIT); }
|
something: whatever SOMETOKEN otherstuff {
/* our context sensitive C code goes here */
};
char StrVars[128][64]; /* up to 128 text variables, max name length 64 chars each */ char NumVars[128][64]; /* up to 128 numeric variables, max name length 64 chars each */ int numSVs = 0; /* initially 0 text variables */ int numNVs = 0; /* initially 0 numeric variables */ int getType(char varname[]); /* return 0 if numeric, 1 if text, -1 if undeclared */ int insert(char varname[], int vartype); /* insert var in appropriate list, return 1 if ok or 0 on fail */ |
int getType(char varname[])
{
for (int i = 0; i < numNVs; i++) {
if (strcmp(NumVars[i], varname) == 0) return 0;
}
return -1;
}
int insert(char varname[], int vartype)
{
if (getType(varname) != -1) {
return -1;
}
if (vartype == 0) {
if (numNVs >= 128) {
return -1;
}
strncpy(NumVars[numNVs++],varname, 64);
return 1;
}
return -1;
}
|
vardecl: NUMDEF IDENT {
if (insert( $<info.content>2, 0 ) == -1) {
yyerror("Attempted numeric variable declaration failed");
}
} ;
|
inputstmt: READ IDENT {
if (getType($<info.content>2) == -1) {
yyerror("Error: attempt to read into undeclared identifier");
}
};
|
expr: value { <$info.type>$ = $<info.type>1; };
value: IDENT { $<info.type>$ = getType($<info.content>1); };
value: STRLIT { $<info.type>$ = 1; };
value: NUMLIT { $<info.type>$ = 0; };
|