package net.jangaroo.jooc; import net.jangaroo.jooc.input.InputSource; import net.jangaroo.jooc.util.IncludeEvaluator; import java.io.IOException; import java.io.Reader; import java.util.HashMap; import java.util.Map; public abstract class ScannerBase implements sym { private StringBuilder whitespace = new StringBuilder(); private StringBuilder multiStateText = new StringBuilder(); private StringBuilder string = new StringBuilder(); private String fileName = ""; private int vectorNestingLevel = 0; protected InputSource inputSource; private JooSymbol pushedBackToken; // error reporting: private final static Map<Integer, String> symbolMap = new HashMap<Integer, String>(50); // the scan routine generated by jFlex public abstract java_cup.runtime.Symbol scan() throws java.io.IOException; // the scan routine called by CUP @SuppressWarnings({"UnusedDeclaration"}) public java_cup.runtime.Symbol next_token() throws java.io.IOException { // NOSONAR required by CUP if (pushedBackToken != null) { JooSymbol result = pushedBackToken; pushedBackToken = null; return result; } return scan(); } /** * Pushback the current token so that it will be read again the next time next_token() is called * * @param token the token */ public void pushback(JooSymbol token) { assert pushedBackToken == null; pushedBackToken = token; } public InputSource getInputSource() { return inputSource; } public void setInputSource(InputSource in) { this.inputSource = in; this.fileName = in.getPath(); } public Reader createIncludeReader(String include) throws IOException { return IncludeEvaluator.createReader(include, getInputSource()); } protected abstract void yypushback(int number); protected abstract void yybeginRegExpStart(); protected void startRegexp(JooSymbol regexpStart) { setMultiStateText(""); clearString(); popWhitespace(); pushWhitespace(regexpStart.getWhitespace()); assert(regexpStart.sym == sym.DIV || regexpStart.sym == sym.DIVEQ); yypushback(regexpStart.getText().length()); // scan it again as part of the regexp yybeginRegExpStart(); } protected void startType(JooSymbol typeStart) { assert(typeStart.sym == sym.MULTEQ); JooSymbol mul = new JooSymbol(sym.MUL, typeStart.getFileName(), typeStart.getLine(), typeStart.getColumn(), "", "*"); pushback(mul); yypushback(1); // the "=" } protected void pushWhitespace(String whitespace) { if (inputSource.isInSourcePath()) { this.whitespace.append(whitespace); } } protected String popWhitespace() { String result = whitespace.toString(); whitespace.setLength(0); return result; } protected void pushString(String string) { this.string.append(string); } protected void pushString(char chr) { this.string.append(chr); } protected void setMultiStateText(String multiStateText) { this.multiStateText.setLength(0); pushMultiStateText(multiStateText); } protected void pushMultiStateText(String multiStateText) { this.multiStateText.append(multiStateText); } protected void increaseVectorNestingLevel() { ++vectorNestingLevel; } protected boolean decreaseVectorNestingLevel() { return --vectorNestingLevel == 0; } protected void clearString() { string.setLength(0); } protected String getString() { return string.toString(); } protected abstract int getLine(); protected abstract int getColumn(); protected abstract String yytext(); protected JooSymbol symbol(int sym) { return new JooSymbol(sym, fileName, getLine(), getColumn(), popWhitespace(), yytext()); } protected JooSymbol symbol(int sym, Object value) { return new JooSymbol(sym, fileName, getLine(), getColumn(), popWhitespace(), yytext(), value); } protected JooSymbol multiStateSymbol(int sym, Object value) { return new JooSymbol(sym, fileName, getLine(), getColumn(), popWhitespace(), multiStateText.toString(), value); } protected void error(String msg) throws ScanError { throw new ScanError(msg, symbol(SCAN_ERROR)); } static protected void defsym(String abbrev, int sym) { symbolMap.put(sym, abbrev); } public String getSymbolAbbreviation(int sym) { String value = symbolMap.get(sym); if (value != null) { return "'" + value + "'"; } switch (sym) { case INT_LITERAL: return "integer literal"; case FLOAT_LITERAL: return "float literal"; case STRING_LITERAL: return "string literal"; case BOOL_LITERAL: return "boolean literal"; case REGEXP_LITERAL: return "regular expression literal"; case IDE: return "identifier"; case EOF: return "End of File"; case NO_LINE_TERMINATOR_HERE: return "NO_LINE_TERMINATOR_HERE"; case NO_LINE_TERMINATOR_HERE_POSTFIX_OP: return "NO_LINE_TERMINATOR_HERE_POSTFIX_OP"; } return "??" + sym + "??"; } static { defsym("as", AS); defsym("break", BREAK); defsym("case", CASE); defsym("catch", CATCH); defsym("class", CLASS); defsym("const", CONST); defsym("continue", CONTINUE); defsym("default", DEFAULT); defsym("delete", DELETE); defsym("do", DO); defsym("else", ELSE); defsym("extends", EXTENDS); defsym("finally", FINALLY); defsym("for", FOR); defsym("function", FUNCTION); defsym("if", IF); defsym("implements", IMPLEMENTS); defsym("import", IMPORT); defsym("in", IN); defsym("instanceof", INSTANCEOF); defsym("interface", INTERFACE); defsym("internal", INTERNAL); defsym("is", IS); defsym("new", NEW); defsym("null", NULL_LITERAL); defsym("package", PACKAGE); defsym("private", PRIVATE); defsym("protected", PROTECTED); defsym("public", PUBLIC); defsym("return", RETURN); defsym("super", SUPER); defsym("switch", SWITCH); defsym("this", THIS); defsym("throw", THROW); defsym("try", TRY); defsym("typeof", TYPEOF); defsym("use", USE); defsym("var", VAR); defsym("void", VOID); defsym("while", WHILE); defsym("with", WITH); defsym("(", LPAREN); defsym(")", RPAREN); defsym("{", LBRACE); defsym("{", LBRACE_EXPR); defsym("}", RBRACE); defsym("[", LBRACK); defsym("]", RBRACK); defsym(";", SEMICOLON); defsym(",", COMMA); defsym(".", DOT); defsym("=", EQ); defsym(">", GT); defsym("<", LT); defsym("!", NOT); defsym("?", QUESTION); defsym(":", COLON); defsym("==", EQEQ); defsym("<=", LTEQ); defsym(">=", GTEQ); defsym("!=", NOTEQ); defsym("&&", ANDAND); defsym("||", OROR); defsym("++", PLUSPLUS); defsym("--", MINUSMINUS); defsym("+", PLUS); defsym("-", MINUS); defsym("*", MUL); defsym("/", DIV); defsym("&", AND); defsym("|", OR); defsym("^", XOR); defsym("%", MOD); defsym("~", BITNOT); defsym("<<", LSHIFT); defsym(">>", RSHIFT); defsym(">>>", URSHIFT); defsym("+=", PLUSEQ); defsym("-=", MINUSEQ); defsym("*=", MULTEQ); defsym("/=", DIVEQ); defsym("&=", ANDEQ); defsym("|=", OREQ); defsym("^=", XOREQ); defsym("%=", MODEQ); defsym("<<=", LSHIFTEQ); defsym(">>=", RSHIFTEQ); defsym(">>>=", URSHIFTEQ); defsym("===", EQEQEQ); defsym("!==", NOTEQEQ); defsym("...", REST); defsym(".<", DOTLT); defsym("::", NAMESPACESEP); } static class ScanError extends RuntimeException { private JooSymbol sym; public ScanError(String msg, JooSymbol sym) { super(msg); this.sym = sym; } public JooSymbol getSym() { return sym; } public void setSym(JooSymbol sym) { this.sym = sym; } } }