%{ #pragma warning(disable:4786) #ifndef STL_INC #define STL_INC #include #include #include #include #include using namespace std; #endif #include "jbc.h" #include "jbcparse.hpp" #include #define yywrap() 1 //文字列処理用 void yyerror(char *message); int nowline=0; #define ALLOC_SIZE 32 /* バッファの(再)割り当て用 */ #define isodigit(x) ((x) >= '0' && (x) <= '7') #define hextoint(x) (isdigit((x)) ? (x) - '0'\ : ((x) - 'A') + 10) %} %option c++ %option stack %option yylineno %option case-insensitive ID [a-zA-Z][_a-zA-Z0-9]* ws [ \t] digit [0-9] hex_digit [0-9a-fA-F] oct_digit [0-7] exponent [eE][+-]?{digit}+ i {digit}+ float_constant ({i}\.{i}?|{i}?\.{i}){exponent}? hex_constant 0[xX]{hex_digit}+ oct_constant 0{oct_digit}+ int_constant {digit}+ float_ext [fF] %x comment_line %x comment_block %x string %% "'" { BEGIN(comment_line);} "//" { BEGIN(comment_line);} "/*" { BEGIN(comment_block);} #予約語関連 sub { yylval.lineno=lineno(); return(T_SUB); } function { yylval.lineno=lineno(); return(T_FUNCTION); } dim { yylval.lineno=lineno(); return(T_DIM); } redim { yylval.lineno=lineno(); return(T_REDIM); } as { yylval.lineno=lineno(); return(T_AS); } int { yylval.lineno=lineno(); return(T_TINT); } float { yylval.lineno=lineno(); return(T_TFLOAT); } string { yylval.lineno=lineno(); return(T_TSTRING); } if { yylval.lineno=lineno(); return(T_IF); } else{ws}*if { yylval.lineno=lineno(); return(T_ELSEIF); } else { yylval.lineno=lineno(); return(T_ELSE); } then { yylval.lineno=lineno(); return(T_THEN); } end{ws}*if { yylval.lineno=lineno(); return(T_ENDIF); } for { yylval.lineno=lineno(); return(T_FOR); } next { yylval.lineno=lineno(); return(T_NEXT); } to { yylval.lineno=lineno(); return(T_TO); } step { yylval.lineno=lineno(); return(T_STEP); } do { yylval.lineno=lineno(); return(T_DO); } loop { yylval.lineno=lineno(); return(T_LOOP); } while { yylval.lineno=lineno(); return(T_WHILE); } until { yylval.lineno=lineno(); return(T_UNTIL); } continue { yylval.lineno=lineno(); return(T_CONTINUE); } return { yylval.lineno=lineno(); return(T_RETURN); } call { yylval.lineno=lineno(); return(T_CALL); } end { yylval.lineno=lineno(); return(T_END); } exit { yylval.lineno=lineno(); return(T_EXIT); } # //意味が複数ある - = 以外の処理 # //2文字あるものは先に処理 "++" { yylval.lineno=lineno();return(T_INC);} "--" { yylval.lineno=lineno();return(T_DEC);} "or" | "||" { yylval.lineno=lineno();return(T_BOOLOR); } "and" | "&&" { yylval.lineno=lineno();return(T_BOOLAND); } "xor" | "^^" { yylval.lineno=lineno();return(T_BOOLXOR); } "!!" { yylval.lineno=lineno();return(T_BOOLNOT); } "<<" { yylval.lineno=lineno();return(T_LSHIFT); } ">>" { yylval.lineno=lineno();return(T_RSHIFT); } "<>" { yylval.lineno=lineno();return(T_NE); } "><" { yylval.lineno=lineno();return(T_NE); } "!=" { yylval.lineno=lineno();return(T_NE); } "<=" { yylval.lineno=lineno();return(T_LE); } "=<" { yylval.lineno=lineno();return(T_LE); } ">=" { yylval.lineno=lineno();return(T_GE); } "=>" { yylval.lineno=lineno();return(T_GE); } "+=" { yylval.lineno=lineno();return(T_EQADD);} "-=" { yylval.lineno=lineno();return(T_EQSUB);} "*=" { yylval.lineno=lineno();return(T_EQMUL);} "/=" { yylval.lineno=lineno();return(T_EQDIV);} "%=" { yylval.lineno=lineno();return(T_EQMOD);} "|=" { yylval.lineno=lineno();return(T_EQOR);} "&=" { yylval.lineno=lineno();return(T_EQAND);} "^=" { yylval.lineno=lineno();return(T_EQXOR);} "<<=" { yylval.lineno=lineno();return(T_EQLS);} ">>=" { yylval.lineno=lineno();return(T_EQRS);} "+" { yylval.lineno=lineno();return(T_PLUS); } "*" { yylval.lineno=lineno();return(T_MULT); } "/" { yylval.lineno=lineno();return(T_DIV); } "mod" | "%" { yylval.lineno=lineno();return(T_MOD); } "|" { yylval.lineno=lineno();return(T_BITOR); } "&" { yylval.lineno=lineno();return(T_BITAND); } "^" { yylval.lineno=lineno();return(T_BITXOR); } "!" { yylval.lineno=lineno();return(T_BITNOT); } "<" { yylval.lineno=lineno();return(T_LT); } ">" { yylval.lineno=lineno();return(T_GT); } "-" { yylval.lineno=lineno();return(T_MINUS); } "=" { yylval.lineno=lineno();return(T_EQ); } "(" { yylval.lineno=lineno();return(T_LPAREN); } ")" { yylval.lineno=lineno();return(T_RPAREN); } "[" { yylval.lineno=lineno();return(T_LBRACKET); } "]" { yylval.lineno=lineno();return(T_RBRACKET); } "," { yylval.lineno=lineno();return(T_COMMA); } {ID} { yylval.expr=new Expression; yylval.expr->lineno=lineno(); yylval.expr->exprtype=T_ID; yylval.expr->index=GetIndexfromIDList(&IDlist,yytext); return(T_ID); } # //文字列の取得 (flex manualより) \" { int inch,count,max_size,temp; char *buffer; buffer = (char*)malloc(ALLOC_SIZE); max_size = ALLOC_SIZE; inch = yyinput(); count = 0; while(inch != EOF && inch != '"' && inch != '\n'){ if(inch == '\\'){ inch = yyinput(); switch(inch){ case '\n': inch = yyinput(); break; case 't' : inch = '\t'; break; case 'n' : inch = '\n'; break; case 'r' : inch = '\r'; break; case 'X' : case 'x' : inch = yyinput(); if(isxdigit(inch)){ temp = hextoint(toupper(inch)); inch = yyinput(); if(isxdigit(inch)) temp = (temp << 4) + hextoint(toupper(inch)); else unput(inch); inch = temp; } else { unput(inch); inch = 'x'; } break; default: if(isodigit(inch)){ temp = inch - '0'; inch = yyinput(); if(isodigit(inch)) temp = (temp << 3) + (inch - '0'); else { unput(inch); goto done; } inch = yyinput(); if(isodigit(inch)) temp = (temp << 3) + (inch - '0'); else unput(inch); done: inch = temp; } } } buffer[count++] = inch; if(count >= max_size){ buffer = (char*)realloc(buffer,max_size + ALLOC_SIZE); max_size += ALLOC_SIZE; } inch = yyinput(); } if(inch == EOF || inch == '\n') yyerror("Unterminated string."); buffer[count] = '\0'; yylval.expr=new Expression; yylval.expr->lineno=lineno(); yylval.expr->type=T_STRING; yylval.expr->exprtype=T_CONST; Strlist.push_back(buffer); yylval.expr->index=Strlist.size()-1; nowline=lineno()+1; return(T_STRING); } # //数値の取得 (flex manualより) {hex_constant} { yylval.expr=new Expression; sscanf(&yytext[2],"%lx",&yylval.expr->ival); yylval.expr->lineno=lineno(); yylval.expr->type=T_INT; yylval.expr->exprtype=T_CONST; return(T_INT);} {oct_constant} { yylval.expr=new Expression; sscanf(&yytext[2],"%lo",&yylval.expr->ival); yylval.expr->lineno=lineno(); yylval.expr->type=T_INT; yylval.expr->exprtype=T_CONST; return(T_INT);} {int_constant} { yylval.expr=new Expression; sscanf(yytext,"%ld",&yylval.expr->ival); yylval.expr->lineno=lineno(); yylval.expr->type=T_INT; yylval.expr->exprtype=T_CONST; return(T_INT);} {int_constant}f { yylval.expr=new Expression; sscanf(yytext,"%f",&yylval.expr->ival); yylval.expr->lineno=lineno(); yylval.expr->type=T_INT; yylval.expr->exprtype=T_CONST; return(T_INT);} {float_constant}{float_ext} | {float_constant} { yylval.expr=new Expression; sscanf(yytext,"%f",&yylval.expr->fval); yylval.expr->lineno=lineno(); yylval.expr->type=T_FLOAT; yylval.expr->exprtype=T_CONST; return(T_FLOAT);} "_"{ws}*\n {nowline=lineno()+1;} ^{ws}*\n {nowline=lineno()+1;} \n {nowline=lineno()+1;yylval.lineno=lineno();return '\n';} {ws} . #コメントブロック [^\n]+ {nowline=lineno()+1;} [\n] { BEGIN(INITIAL);} "*/" { BEGIN(INITIAL);} [*/] [^*/\n]+ {nowline=lineno()+1;} [\n] {nowline=lineno()+1;} %%