/*===-- Lexer.l - Scanner for Stacker language -----------------*- C++ -*--===// // // The LLVM Compiler Infrastructure // // This file was developed by Reid Spencer and donated to the LLVM research // group and is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements the flex scanner for Stacker languages files. // //===----------------------------------------------------------------------===*/ %option prefix="Stacker" %option yylineno %option nostdinit %option never-interactive %option batch %option noyywrap %option nodefault %option 8bit %option outfile="Lexer.cpp" %option ecs %option noreject %option noyymore %{ #include "StackerCompiler.h" #include "StackerParser.h" /* Conversion of text ints to binary */ static int64_t IntToVal(const char *Buffer) { int64_t Result = 0; for (; *Buffer; Buffer++) { int64_t OldRes = Result; Result *= 10; Result += *Buffer-'0'; if (Result < OldRes) // Uh, oh, overflow detected!!! StackerCompiler::ThrowException("constant bigger than 64 bits detected!"); } return Result; } /* Conversion of text hexadecimal ints to binary */ static int64_t HexIntToVal(const char *Buffer) { int64_t Result = 0; for (; *Buffer; ++Buffer) { int64_t OldRes = Result; Result *= 16; char C = *Buffer; if (C >= '0' && C <= '9') Result += C-'0'; else if (C >= 'A' && C <= 'F') Result += C-'A'+10; else if (C >= 'a' && C <= 'f') Result += C-'a'+10; if (Result < OldRes) // Uh, oh, overflow detected!!! StackerCompiler::ThrowException("constant bigger than 64 bits detected!"); } return Result; } #define YY_NEVER_INTERACTIVE 1 %} /* Comments start with a ; and go till end of line */ Comment1 [#].*$ /* You can also embed them in ( ... ) */ Comment2 \(.*\) /* We ignore white space */ White [ \t\n] /* jdentifiers start with a % sign */ Identifier [A-Za-z][-A-Za-z0-9_]* /* Strings can contain any character except " and \ */ String \"[^\"]*\" /* Positive and negative integer constants*/ PInteger [+]?[0-9]+ NInteger -[0-9]+ HexInteger 0x[0-9A-Fa-f]+ /* Special Characters - name them to avoid flex confusion */ Semi [;] Colon [:] Less \< More \> LessEq \<\= MoreEq \>\= NotEq \<\> Equal \= Plus \+ Minus \- Incr \+\+ Decr \-\- Mult \* Div \/ StarSlash \*\/ LShift \<\< RShift \>\> InStr \s OutNum \>d OutChar \>c %% {Comment1} { /* Ignore comments */ } {Comment2} { /* Ignore comments */ } {Colon} { return COLON; } {Semi} { return SEMI; } TRUE { return TRUETOK; } FALSE { return FALSETOK; } ON { return TRUETOK; } OFF { return FALSETOK; } {Less} { return LESS; } LT { return LESS; } {More} { return MORE; } GT { return MORE; } {LessEq} { return LESS_EQUAL; } LE { return LESS_EQUAL; } {MoreEq} { return MORE_EQUAL; } GE { return MORE_EQUAL; } {NotEq} { return NOT_EQUAL; } NE { return NOT_EQUAL; } {Equal} { return EQUAL; } EQ { return EQUAL; } {Plus} { return PLUS; } {Minus} { return MINUS; } {Incr} { return INCR; } {Decr} { return DECR; } {Mult} { return MULT; } {Div} { return DIV; } MOD { return MODULUS; } NEG { return NEGATE; } ABS { return ABS; } MIN { return MIN; } MAX { return MAX; } {StarSlash} { return STAR_SLASH; } AND { return AND; } OR { return OR; } XOR { return XOR; } {LShift} { return LSHIFT; } {RShift} { return RSHIFT; } DROP { return DROP; } NIP { return NIP; } DUP { return DUP; } SWAP { return SWAP; } OVER { return OVER; } PICK { return PICK; } SELECT { return SELECT; } ROT { return ROT; } RROT { return RROT; } ROLL { return ROLL; } TUCK { return TUCK; } DROP2 { return DROP2; } NIP2 { return NIP2; } DUP2 { return DUP2; } SWAP2 { return SWAP2; } OVER2 { return OVER2; } TUCK2 { return TUCK2; } ROT2 { return ROT2; } RROT2 { return RROT2; } MALLOC { return MALLOC; } FREE { return FREE; } GET { return GET; } PUT { return PUT; } IF { return IF; } ELSE { return ELSE; } ENDIF { return ENDIF; } WHILE { return WHILE; } END { return END; } RECURSE { return RECURSE; } RETURN { return RETURN; } EXIT { return EXIT; } FORWARD { return FORWARD; } TAB { return TAB; } SPACE { return SPACE; } CR { return CR; } {InStr} { return IN_STR; } {InNum} { return IN_NUM; } {InChar} { return IN_CHAR; } {OutStr} { return OUT_STR; } {OutNum} { return OUT_NUM; } {OutChar} { return OUT_CHAR; } MAIN { return MAIN; } DUMP { return DUMP; } != { StackerCompiler::ThrowException( "You probably meant to use a <> instead of !=" ); } == { StackerCompiler::ThrowException( "You probably meant to use a single = .. this isn't C"); } {PInteger} { Stackerlval.IntegerVal = IntToVal(yytext); return INTEGER; } {NInteger} { uint64_t Val = IntToVal(yytext+1); // +1: we have bigger negative range if (Val > (uint64_t)INT64_MAX+1) StackerCompiler::ThrowException( "Constant too large for signed 64 bits!"); Stackerlval.IntegerVal = -Val; return INTEGER; } {HexInteger} { Stackerlval.IntegerVal = HexIntToVal(yytext+3); return INTEGER; } {String} { yytext[strlen(yytext)-1] = 0; // nuke end quote Stackerlval.StringVal = strdup(yytext+1); // Nuke start quote return STRING; } {Identifier} { Stackerlval.StringVal = strdup(yytext); return IDENTIFIER; } {White} { /* Ignore whitespace */ } %%