package org.jastadd.tooling.aspect.lexer; import com.intellij.lexer.FlexLexer; import com.intellij.psi.tree.IElementType; import org.jastadd.tooling.aspect.psi.AspectTypes; import com.intellij.psi.TokenType; %% %class AspectLexer %implements FlexLexer %unicode %function advance %type IElementType %eof{ %eof} %{ private int counter = 0; private int totalBraceLevel = 0; private java.util.Stack<Integer> modeStack = new java.util.Stack<>(); private void enterState(int state) { modeStack.push(yystate()); yybegin(state); } private void exitState() { yybegin(modeStack.pop()); } %} WhiteSpace = [ \t\n\r\f] // TODO what is /**/ in Java? Is this caputered here? SingleLineComment = "//" [^\n\r]* FormalComment = "/**" [^*]* [*]+([^*/][^*]*[*]+)*[/] MultiLineComment = "/*" [^*]+ [*]+([^*/][^*]*[*]+)*[/] // from jjt DecimalLiteral = [1-9] [0-9]* HexLiteral = 0 [xX] [0-9a-fA-F]+ OctalLiteral = 0 [0-7]* IntegerLiteral = ( {DecimalLiteral} | {HexLiteral} | {OctalLiteral} ) [lL]? Exponent = [eE] [+-]? [0-9]+ FloatingPointLiteral = [0-9]+ "." [0-9]* {Exponent}? [fFdD]? | "." [0-9]+ {Exponent}? [fFdD]? | [0-9]+ {Exponent} [fFdD]? | [0-9]+ {Exponent}? [fFdD] CharacterLiteral = ' ( [^'\\\n\r] | ( \\ ( [ntbrf\\'\"] | [0-7][0-7?] | [0-3][0-7][0-7] ) ) ) ' StringLiteral = \" ( [^\"\\\n\r] | ( \\ ( [ntbrf\\'\"] | [0-7][0-7?] | [0-3][0-7][0-7] ) ) )* \" Identifier = [:jletter:] [:jletterdigit:]* %state IN_ASPECT %state COLLECTION_DECL %state ATTRIBUTE_DEFINITION %% <YYINITIAL,IN_ASPECT,COLLECTION_DECL,ATTRIBUTE_DEFINITION> { {WhiteSpace}+ { return TokenType.WHITE_SPACE; } {SingleLineComment} { return AspectTypes.SINGLE_LINE_COMMENT; } {FormalComment} { return AspectTypes.FORMAL_COMMENT; } {MultiLineComment} { return AspectTypes.MULTI_LINE_COMMENT; } } <YYINITIAL,IN_ASPECT,COLLECTION_DECL,ATTRIBUTE_DEFINITION> { "abstract" { return AspectTypes.ABSTRACT; } "assert" { return AspectTypes.ASSERT; } "boolean" { return AspectTypes.BOOLEAN; } "break" { return AspectTypes.BREAK; } "byte" { return AspectTypes.BYTE; } "case" { return AspectTypes.CASE; } "catch" { return AspectTypes.CATCH; } "char" { return AspectTypes.CHAR; } "class" { return AspectTypes.CLASS; } "const" { return AspectTypes.CONST; } "continue" { return AspectTypes.CONTINUE; } "default" { return AspectTypes.DEFAULT; } "do" { return AspectTypes.DO; } "double" { return AspectTypes.DOUBLE; } "else" { return AspectTypes.ELSE; } "enum" { return AspectTypes.ENUM; } "extends" { return AspectTypes.EXTENDS; } "false" { return AspectTypes.FALSE; } "final" { return AspectTypes.FINAL; } "finally" { return AspectTypes.FINALLY; } "float" { return AspectTypes.FLOAT; } "for" { return AspectTypes.FOR; } "goto" { return AspectTypes.GOTO; } "if" { return AspectTypes.IF; } "implements" { return AspectTypes.IMPLEMENTS; } "import" { return AspectTypes.IMPORT; } "instanceof" { return AspectTypes.INSTANCEOF; } "int" { return AspectTypes.INT; } "interface" { return AspectTypes.INTERFACE; } "long" { return AspectTypes.LONG; } "native" { return AspectTypes.NATIVE; } "new" { return AspectTypes.NEW; } "null" { return AspectTypes.NULL; } "package" { return AspectTypes.PACKAGE; } "private" { return AspectTypes.PRIVATE; } "protected" { return AspectTypes.PROTECTED; } "public" { return AspectTypes.PUBLIC; } "return" { return AspectTypes.RETURN; } "short" { return AspectTypes.SHORT; } "static" { return AspectTypes.STATIC; } "strictfp" { return AspectTypes.STRICTFP; } "super" { return AspectTypes.SUPER; } "switch" { return AspectTypes.SWITCH; } "synchronized" { return AspectTypes.SYNCHRONIZED; } "this" { return AspectTypes.THIS; } "throw" { return AspectTypes.THROW; } "throws" { return AspectTypes.THROWS; } "transient" { return AspectTypes.TRANSIENT; } "true" { return AspectTypes.TRUE; } "try" { return AspectTypes.TRY; } "void" { return AspectTypes.VOID; } "volatile" { return AspectTypes.VOLATILE; } "while" { return AspectTypes.WHILE; } // the only jastadd-specific keyword here is aspect "aspect" { enterState(IN_ASPECT); return AspectTypes.ASPECT; } } <IN_ASPECT,COLLECTION_DECL,ATTRIBUTE_DEFINITION> { "inh" { enterState(ATTRIBUTE_DEFINITION); return AspectTypes.INH; } "syn" { enterState(ATTRIBUTE_DEFINITION); return AspectTypes.SYN; } "lazy" { return AspectTypes.LAZY; } "rewrite" { return AspectTypes.REWRITE; } "to" { return AspectTypes.TO; } "when" { return AspectTypes.WHEN; } "eq" { enterState(ATTRIBUTE_DEFINITION); return AspectTypes.EQUATION; } "circular" { return AspectTypes.CIRCULAR; } "refine" { return AspectTypes.REFINE; } "contributes" { return AspectTypes.CONTRIBUTES; } "each" { return AspectTypes.EACH; } "nta" { return AspectTypes.NTA; } "cache" { return AspectTypes.CACHE; } "uncache" { return AspectTypes.UNCACHE; } // TODO this is strangely split in another Token block, check semantics of JJTree file! "coll" { enterState(COLLECTION_DECL); return AspectTypes.COLL; } } <COLLECTION_DECL> { "with" { return AspectTypes.WITH; } "root" { return AspectTypes.ROOT; } "[" { return AspectTypes.LBRACKET; } } <ATTRIBUTE_DEFINITION> { "{" { ++totalBraceLevel; return AspectTypes.LBRACE; } } // a semicolon exits the COLLECTION_DECL (because we ignore semicolons in expressions) <COLLECTION_DECL, ATTRIBUTE_DEFINITION> { ";" { exitState(); return AspectTypes.SEMICOLON; } } <YYINITIAL,IN_ASPECT,COLLECTION_DECL,ATTRIBUTE_DEFINITION> { // LITERALS {IntegerLiteral} { return AspectTypes.INTEGER_LITERAL; } {FloatingPointLiteral} { return AspectTypes.FLOATING_POINT_LITERAL; } {CharacterLiteral} { return AspectTypes.CHARACTER_LITERAL; } {StringLiteral} { return AspectTypes.STRING_LITERAL; } // IDENTIFIERS {Identifier} { return AspectTypes.IDENTIFIER; } // SEPARATORS "(" { return AspectTypes.LPAREN; } ")" { return AspectTypes.RPAREN; } "{" { ++totalBraceLevel; return AspectTypes.LBRACE; } "}" { --totalBraceLevel; if (totalBraceLevel == 0) { exitState(); } return AspectTypes.RBRACE; } "[" { return AspectTypes.LBRACKET; } "]" { return AspectTypes.RBRACKET; } ";" { return AspectTypes.SEMICOLON; } "," { return AspectTypes.COMMA; } "." { return AspectTypes.DOT; } "@" { return AspectTypes.AT; } // OPERATORS "=" { return AspectTypes.ASSIGN; } "<" { return AspectTypes.LT; } "!" { return AspectTypes.BANG; } "~" { return AspectTypes.TILDE; } "?" { return AspectTypes.QUESTIONMARK; } ":" { return AspectTypes.COLON; } "==" { return AspectTypes.EQ; } "<=" { return AspectTypes.LE; } ">=" { return AspectTypes.GE; } "!=" { return AspectTypes.NE; } "||" { return AspectTypes.SC_OR; } "&&" { return AspectTypes.SC_AND; } "++" { return AspectTypes.INCR; } "--" { return AspectTypes.DECR; } "+" { return AspectTypes.PLUS; } "-" { return AspectTypes.MINUS; } "*" { return AspectTypes.STAR; } "/" { return AspectTypes.SLASH; } "&" { return AspectTypes.BIT_AND; } "|" { return AspectTypes.BIT_OR; } "^" { return AspectTypes.XOR; } "%" { return AspectTypes.REM; } "<<" { return AspectTypes.LSHIFT; } "+=" { return AspectTypes.PLUSASSIGN; } "-=" { return AspectTypes.MINUSASSIGN; } "*=" { return AspectTypes.STARASSIGN; } "/=" { return AspectTypes.SLASHASSIGN; } "&=" { return AspectTypes.ANDASSIGN; } "|=" { return AspectTypes.ORASSIGN; } "^=" { return AspectTypes.XORASSIGN; } "%=" { return AspectTypes.REMASSIGN; } "<<=" { return AspectTypes.LSHIFTASSIGN; } ">>=" { return AspectTypes.RSIGNEDSHIFTASSIGN; } ">>>=" { return AspectTypes.RUNSIGNEDSHIFTASSIGN; } "..." { return AspectTypes.ELLIPSIS; } "->" { return AspectTypes.ARROW; } "::" { return AspectTypes.DOUBLECOLON; } // TODO RUNSIGNEDSHIFT >>> and RSIGNEDSHIFT >> are not parsed ">" { return AspectTypes.GT; } }