// This is for UCSD CSE 141L, Spring 2006. -Wei and JSampson // // This is some sample code to parse an assembly instruction. Compile with // the provided Makefile. // To run do: // > scanner // #include "token.h" #include #include #include int debug = 0; // flex interface declaration // plus some required functions #ifdef __cplusplus extern "C" { #endif extern int yylex(void); extern char* yytext; extern FILE* yyin; // API requires two functions to be defined by external caller int yywrap (void) { return 1; } int yyerror (char* msg) { fprintf(stderr, "lexing error %s\n", msg); return 0; } #ifdef __cplusplus } #endif // Keep track of input file state for debug int inst_count=0; int line_count=0; // Defines scanner state machine, to figure out if processing operands // State machine can also be placed in flex input .l file. enum parse_state_t { state_start = 0, state_oper = 1 }; // This uses flex to tokenize strings, and return back what type of // token it is. Depending on the type it prints out a different // message. // Assumes that FILE* yyin variable has been initialized. yyin needs // to point to the input text file. int parse_inst() { int token; int index; int oper_index = 0; int cii = 0; int cop = 0; int value; inst_count = 0; line_count = 1; parse_state_t state=state_start; // Keeps track of line number, and if currently parsing an // instruction followed by operands. // yylex returns an integer with a correponding token tag // prints out debug message while(token = yylex() ) { switch(token) { case NEWLINE: state=state_start; line_count++; break; case TOKEN: switch(state) { case state_start: printf("I have found an instruction TOKEN %s at line %d\n", yytext, line_count); state = state_oper; // state machine can also implemented in flex break; case state_oper: printf("\t operand TOKEN %s at line %d\n", yytext, line_count); break; } break; case LABEL: printf("I have found an LABEL %s at line %d\n", yytext, line_count); break; default: printf("I dont recognize %s at line %d\n", yytext, line_count); } } return inst_count; } // good to provide usage info int help(char* error) { printf("usage: scanner [-d] [-h] input\n"); printf(" [-d] debug\n"); printf(" [-h] help\n"); printf("error: %s\n", error); } // main 1st checks args // then initializes yyin // then calls flex generated code through parse_inst, which call yylex() int main(int argc, char** argv) { int arg_index = 1; if(argc<1) { help("wrong number of args"); exit(0); } while(arg_index