/** Find stop token index of next operator; return -1 if not operator. */ public static int getLastOpTokenIndex(ITokenStream tokens) { var i = tokens.Index; // current on-channel lookahead token index var lt = tokens.Get(i); if (lt.getType() == SwiftParser.DOT && tokens.get(i + 1).getType() == SwiftParser.DOT) { // dot-operator i += 2; // point at token after ".." lt = tokens.get(i); while (lt.getType() != Token.EOF && (lt.getType() == SwiftParser.DOT || isOperatorChar(lt.getType()))) { i++; lt = tokens.get(i); } return(i - 1); } // Is it regular operator? if (!isOperatorHead(lt.getType())) { return(-1); } i++; lt = tokens.get(i); while (lt.getType() != Token.EOF && isOperatorChar(lt.getType())) { i++; lt = tokens.get(i); } int stop = i - 1; return(stop); }
/** Return two booleans packed into lowest 2 bits for left (high) and right (low) * whitespace. */ public static int getLeftRightWS(ITokenStream tokens, ParserRuleContext ctx) { var left = ctx.start.getTokenIndex(); var right = ctx.stop.getTokenIndex(); var prevToken = tokens.get(left - 1); // includes hidden-channel tokens var nextToken = tokens.get(right + 1); var prevIsWS = isLeftOperatorWS(prevToken); var nextIsWS = isRightOperatorWS(nextToken); var b = (prevIsWS ? 1 : 0) << 1 | (nextIsWS ? 1 : 0); return(b); }
/** * "If an operator has whitespace on the left side only, it is treated as a * prefix unary operator. As an example, the ++ operator in a ++b is treated * as a prefix unary operator." */ public static boolean isPrefixOp(ITokenStream tokens) { int stop = getLastOpTokenIndex(tokens); if (stop == -1) { return(false); } var start = tokens.Index; var prevToken = tokens.get(start - 1); // includes hidden-channel tokens var nextToken = tokens.get(stop + 1); var prevIsWS = isLeftOperatorWS(prevToken); var nextIsWS = isRightOperatorWS(nextToken); var result = prevIsWS && !nextIsWS; var text = tokens.GetText(Interval.Of(start, stop)); //System.out.println("isPrefixOp: '"+prevToken+"','"+text+"','"+nextToken+"' is "+result); return(result); }
/** Return two booleans packed into lowest 2 bits for left (high) and right (low) * whitespace. */ public static int getLeftRightWS(ITokenStream tokens, ParserRuleContext ctx) { var left = ctx.start.getTokenIndex(); var right = ctx.stop.getTokenIndex(); var prevToken = tokens.get(left - 1); // includes hidden-channel tokens var nextToken = tokens.get(right + 1); var prevIsWS = isLeftOperatorWS(prevToken); var nextIsWS = isRightOperatorWS(nextToken); var b = (prevIsWS ? 1 : 0) << 1 | (nextIsWS ? 1 : 0); return b; }
/** "If an operator has whitespace on the right side only, it is treated as a postfix unary operator. As an example, the ++ operator in a++ b is treated as a postfix unary operator." "If an operator has no whitespace on the left but is followed immediately by a dot (.), it is treated as a postfix unary operator. As an example, the ++ operator in a++.b is treated as a postfix unary operator (a++ .b rather than a ++ .b)." */ public static boolean isPostfixOp(ITokenStream tokens) { int stop = getLastOpTokenIndex(tokens); if (stop == -1) return false; int start = tokens.Index; var prevToken = tokens.get(start - 1); // includes hidden-channel tokens var nextToken = tokens.get(stop + 1); var prevIsWS = isLeftOperatorWS(prevToken); var nextIsWS = isRightOperatorWS(nextToken); var result = !prevIsWS && nextIsWS || !prevIsWS && nextToken.getType() == SwiftParser.DOT; var text = tokens.GetText(Interval.Of(start, stop)); //System.out.println("isPostfixOp: '"+prevToken+"','"+text+"','"+nextToken+"' is "+result); return result; }
/** Find stop token index of next operator; return -1 if not operator. */ public static int getLastOpTokenIndex(ITokenStream tokens) { var i = tokens.Index; // current on-channel lookahead token index var lt = tokens.Get(i); if (lt.getType() == SwiftParser.DOT && tokens.get(i + 1).getType() == SwiftParser.DOT) { // dot-operator i += 2; // point at token after ".." lt = tokens.get(i); while (lt.getType() != Token.EOF && (lt.getType() == SwiftParser.DOT || isOperatorChar(lt.getType()))) { i++; lt = tokens.get(i); } return i - 1; } // Is it regular operator? if (!isOperatorHead(lt.getType())) { return -1; } i++; lt = tokens.get(i); while (lt.getType() != Token.EOF && isOperatorChar(lt.getType())) { i++; lt = tokens.get(i); } int stop = i - 1; return stop; }