%{ #include "parser.h" #include #include #include static const int MAX_STR_LEN = 1023; static char curstr[MAX_STR_LEN+1]; static int curstr_len = 0; static bool longString = false; void scanError(const char *s, int lineno); %} /* Macro defining the exponent in double constant */ EXP ((E|e)("+"|"-")?[0-9]+) %option yylineno %Start S CCOMM CPPCOMM STR %% { BEGIN S; } "if" { // printf ("scan: IF\n"); return IF; } "else" { return ELSE; } "elseif" { return ELSEIF; } "endif" { return ENDIF; } "while" { return WHILE; } "break" { return BREAK; } "continue" { return CONTINUE; } "return" { return RETURN; } "function" { return FUNCTION; } "func" { return FUNCTION; } "endfunction" { return ENDFUNCTION; } "endfunc" { return ENDFUNCTION; } "global" { return NONLOCAL; } "nonlocal" { return NONLOCAL; } "endwhile" { return ENDWHILE; } "input" { return INPUT; } "output" { return OUTPUT; } "outputln" { return OUTPUTLN; } "end" { return END; } "ref" { return REF; } "int" { // printf ("scan: TYPE (int)\n"); yylval.int_value = TYPE_INT; return TYPE; } "double" { // printf ("scan: TYPE (double)\n"); yylval.int_value = TYPE_DOUBLE; return TYPE; } "string" { // printf ("scan: TYPE (string)\n"); yylval.int_value = TYPE_STRING; return TYPE; } "list" { // printf ("scan: TYPE (string)\n"); yylval.int_value = TYPE_LIST; return TYPE; } "+" { return PLUS; } "-" { return MINUS; } "*" { return MUL; } "/" { return DIV; } "%" { return MOD; } "**"|"^" { return POW; } "(" { // printf ("scan: LPAR\n"); return LPAR; } ")" { // printf ("scan: RPAR\n"); return RPAR; } "[" { return LBR; } "]" { return RBR; } "," { return CM; } ";" { return SM; } "." { return POINT; } "=" { return ASG; } "==" { // printf ("scan: RELOP_EQ\n"); yylval.int_value = RELOP_EQ; return RELOP; } "!=" { // printf ("scan: RELOP_NE\n"); yylval.int_value = RELOP_NE; return RELOP; } ">" { // printf ("scan: RELOP_GT\n"); yylval.int_value = RELOP_GT; return RELOP; } ">=" { // printf ("scan: RELOP_GE\n"); yylval.int_value = RELOP_GE; return RELOP; } "<" { // printf ("scan: RELOP_LT\n"); yylval.int_value = RELOP_LT; return RELOP; } "<=" { // printf ("scan: RELOP_LE\n"); yylval.int_value = RELOP_LE; return RELOP; } "||"|"or" { return LOR; } "&&"|"and" { return LAND; } "!"|"not" { return LNOT; } [a-zA-Z][a-zA-Z0-9]* { // printf("NAME %s\n", yytext); yylval.name = yytext; // printf("NAME %s is added to string pool\n", yytext); return NAME; } (" "|\t)* {} /* Skip space */ /* Integer constant */ [0-9]+ { yylval.int_value = atoi(yytext); return INT_CONST; } /* Double constant may be in one of the following 3 forms: */ /* 1) .5, .5e-20, 1.2, 123.456E+10 (mandatory point and fraction) */ /* 2) 1., 123.e+10, 0.2E-20, 35.3 (mandatory integer and point) */ /* 3) 1e+10, 2e20, 1E-12 (mandatory integer and exponent) */ /* The expression for double is the union "|" of 3 subexpressions */ ([0-9]*"."[0-9]+{EXP}?)|([0-9]+"."[0-9]*{EXP}?)|([0-9]+{EXP}) { yylval.double_value = atof(yytext); return DOUBLE_CONST; } \n|\r\n { /* return ENDL; */ } /* End of line in Unix or MS DOS form */ \" { BEGIN STR; curstr_len = 0; longString = false; } [^"\n\r\t] { if (curstr_len < MAX_STR_LEN) { curstr[curstr_len] = yytext[0]; ++curstr_len; } else { LLongString: ; if (!longString) { longString = true; scanError( "String constant is too long", yylineno ); } } } \\\" { if (curstr_len < MAX_STR_LEN) { curstr[curstr_len] = '\"'; ++curstr_len; } else { goto LLongString; } } \\n { if (curstr_len < MAX_STR_LEN) { curstr[curstr_len] = '\n'; ++curstr_len; } else { goto LLongString; } } \\r { if (curstr_len < MAX_STR_LEN) { curstr[curstr_len] = '\r'; ++curstr_len; } else { goto LLongString; } } \\t { if (curstr_len < MAX_STR_LEN) { curstr[curstr_len] = '\t'; ++curstr_len; } else { goto LLongString; } } \" { LOffString: ; curstr[curstr_len] = 0; yylval.name = curstr; // printf("scan: STRING_CONST: %s\n", yylval.name.c_str()); BEGIN S; return STRING_CONST; } \n|\r\n { scanError( "Nonterminated string constant", yylineno-1 ); goto LOffString; } "/*" { BEGIN CCOMM; } (.|\n) {} "*/" { BEGIN S; } "//"|"#" { BEGIN CPPCOMM; } . {} \n { BEGIN S; } . { return ILLEGAL; } /* Any other character */ %% /*============= The user programs section ===================*/ int yywrap() { return 1; } /* Stop at end of file */ void scanError(const char *s, int line) { fprintf( stderr, "Scanner error: %s in line %d\n", s, line ); wasErrors = true; }