List of usage examples for org.antlr.v4.runtime ParserRuleContext getRuleContext
public <T extends ParserRuleContext> T getRuleContext(Class<? extends T> ctxType, int i)
From source file:com.satisfyingstructures.J2S.J2SConverter.java
License:Open Source License
private void convertVariableDeclaration(ParserRuleContext declarationCtx) { // Read comments in exitVariableDeclaratorId just above! int declarationRuleIndex = declarationCtx.getRuleIndex(); Class<? extends ParserRuleContext> modifierContextClass = Java8Parser.VariableModifierContext.class; Constness constness = Constness.unknown; boolean isOptional = false; boolean hasDeclaratorList = false; boolean enhancedFor = false; switch (declarationRuleIndex) { case Java8Parser.RULE_constantDeclaration: modifierContextClass = Java8Parser.ConstantModifierContext.class; hasDeclaratorList = true;//from w w w. jav a 2 s . c o m constness = Constness.explicit; break; case Java8Parser.RULE_fieldDeclaration: modifierContextClass = Java8Parser.FieldModifierContext.class; hasDeclaratorList = true; break; case Java8Parser.RULE_localVariableDeclaration: hasDeclaratorList = true; break; case Java8Parser.RULE_resource: constness = Constness.explicit; break; case Java8Parser.RULE_formalParameter: case Java8Parser.RULE_lastFormalParameter: constness = Constness.implicit; break; case Java8Parser.RULE_catchFormalParameter: constness = Constness.explicit; break; case Java8Parser.RULE_enhancedForStatement: case Java8Parser.RULE_enhancedForStatementNoShortIf: enhancedFor = true; constness = Constness.implicit; break; default: return; // not our expected parameter type } // Look for and remove 'final', '@NonNull' and '@Nullable' in modifiers for (ParserRuleContext modifierCtx : declarationCtx.getRuleContexts(modifierContextClass)) { TerminalNode tn = modifierCtx.getChild(TerminalNode.class, 0); if (null == tn) { String annotationText = modifierCtx.getText(); switch (annotationText) { // some spelling variations here... case "@Nonnull": // javax.annotation.NotNull case "@NonNull": // android.support.annotation.NonNull // edu.umd.cs.findbugs.annotations.NonNull case "@NotNull": // org.jetbrains.annotations.NotNull isOptional = false; break; case "@Nullable": isOptional = true; break; default: continue; } } else { Token token = tn.getSymbol(); mapModifierToken(token); switch (token.getType()) { case Java8Parser.FINAL: if (constness == Constness.unknown) constness = Constness.explicit; break; default: continue; } } rewriter.deleteAndAdjustWhitespace(modifierCtx); } // Move trailing dimensions to wrap the type. First any dimensions binding to the declarator id and // then any dimensions binding to the right of the type. // a) start by finding the type context that will be wrapped. Java8Parser.UnannTypeContext unannTypeCtx = null; Java8Parser.UnannReferenceTypeContext unannReferenceTypeCtx = null; Java8Parser.UnannArrayTypeContext unannArrayTypeCtx = null; Java8Parser.DimsContext outerDimsCtx = null; ParserRuleContext typeCtx = null; if (declarationRuleIndex == Java8Parser.RULE_catchFormalParameter) typeCtx = declarationCtx.getChild(Java8Parser.CatchTypeContext.class, 0); else typeCtx = unannTypeCtx = declarationCtx.getChild(Java8Parser.UnannTypeContext.class, 0); if (null != unannTypeCtx) if (null != (unannReferenceTypeCtx = unannTypeCtx.unannReferenceType()) && null != (unannArrayTypeCtx = unannReferenceTypeCtx.unannArrayType())) { typeCtx = unannArrayTypeCtx.getChild(ParserRuleContext.class, 0); outerDimsCtx = unannArrayTypeCtx.dims(); } // b) process dimensions attached to declarator ids // ...process inside blocks below // c) process dimensions attached to type // ...process inside blocks below // Now insert unannTypeText at end of each variableDeclaratorId if necessary: ParserRuleContext ctx, varInitCtx; Java8Parser.VariableDeclaratorIdContext varIdCtx; Java8Parser.DimsContext innerDimsCtx = null; String unannTypeText; if (hasDeclaratorList) { // Iterate over the list of declarator-initialiser pairs backwards so that variable lists without // intialisers and with explicit enough types, just pick up the type from the end of the list, i.e. // so that we generate var a, b, c: Int, and not var a: Int, b: Int, c: Int. ListIterator<Java8Parser.VariableDeclaratorContext> iter; List<Java8Parser.VariableDeclaratorContext> list; String followingUnannTypeText = null; boolean followingVarHasExplicitType = false; boolean hasInitialiser; ctx = declarationCtx.getChild(Java8Parser.VariableDeclaratorListContext.class, 0); list = ctx.getRuleContexts(Java8Parser.VariableDeclaratorContext.class); iter = list.listIterator(list.size()); unannTypeText = null; while (iter.hasPrevious()) { ctx = iter.previous(); varIdCtx = ctx.getRuleContext(Java8Parser.VariableDeclaratorIdContext.class, 0); // Wrap the inner type string with array dimensions if we have them. Have to do this for each variable, // because they can have different dimensionality. followingUnannTypeText = unannTypeText; unannTypeText = rewriter.getText(typeCtx); if (null != (innerDimsCtx = varIdCtx.dims())) { unannTypeText = wrapTypeStringWithDims(unannTypeText, innerDimsCtx); rewriter.delete(innerDimsCtx); } if (null != outerDimsCtx) unannTypeText = wrapTypeStringWithDims(unannTypeText, outerDimsCtx); varInitCtx = ctx.getRuleContext(Java8Parser.VariableInitializerContext.class, 0); if (null != varInitCtx) varInitCtx = varInitCtx.getChild(ParserRuleContext.class, 0); // expression or arrayInitializer hasInitialiser = null != varInitCtx; // In the basic case, we have to qualify the variable with its type, but we can omit this if it has an // initialiser that completely implies the type, or it has no initialiser and has the same type as the // a contiguously following variable with explicit type. if (hasInitialiser ? !isVariableTypeCompletelyImpliedByInitializer(unannTypeCtx, varInitCtx, /*inEnhancedFor:*/false) : !followingVarHasExplicitType || null == followingUnannTypeText || !unannTypeText.equals(followingUnannTypeText)) { rewriter.insertAfter(varIdCtx, ": " + unannTypeText + (isOptional ? "?" : "")); followingVarHasExplicitType = !hasInitialiser; } } } else { varIdCtx = declarationCtx.getRuleContext(Java8Parser.VariableDeclaratorIdContext.class, 0); unannTypeText = rewriter.getText(typeCtx); if (null != (innerDimsCtx = varIdCtx.dims())) { unannTypeText = wrapTypeStringWithDims(unannTypeText, innerDimsCtx); rewriter.delete(innerDimsCtx); } if (null != outerDimsCtx) unannTypeText = wrapTypeStringWithDims(unannTypeText, outerDimsCtx); varInitCtx = null; if (declarationRuleIndex == Java8Parser.RULE_resource || declarationRuleIndex == Java8Parser.RULE_enhancedForStatement || declarationRuleIndex == Java8Parser.RULE_enhancedForStatementNoShortIf) varInitCtx = declarationCtx.getRuleContext(Java8Parser.ExpressionContext.class, 0); if (declarationRuleIndex == Java8Parser.RULE_catchFormalParameter) rewriter.insertAfter(varIdCtx, " as " + unannTypeText); else if (!isVariableTypeCompletelyImpliedByInitializer(unannTypeCtx, varInitCtx, enhancedFor)) rewriter.insertAfter(varIdCtx, ": " + unannTypeText + (isOptional ? "?" : "")); // In parameter lists, add an anonymizing argument label, as argument labels not used in java method/function calls if (declarationRuleIndex == Java8Parser.RULE_formalParameter || declarationRuleIndex == Java8Parser.RULE_lastFormalParameter) rewriter.insertBefore(varIdCtx, "_ "); } // Finally replace the complete type context with let/var/- // in an enhancedForStatement, the loop var is implicitly const, but can be made variable with var if it is // to be modified inside the loop; we could check for this, but its a rare scenario, and a lot of work, so no. if (null != unannTypeCtx) typeCtx = unannTypeCtx; switch (constness) { case explicit: rewriter.replace(typeCtx, "let"); break; case implicit: rewriter.deleteAndAdjustWhitespace(typeCtx); break; case variable: rewriter.replace(typeCtx, "var"); break; // if still unknown, then assume variable... default: rewriter.replace(typeCtx, "var"); break; } }
From source file:com.yahoo.yqlplus.language.parser.ProgramParser.java
private OperatorNode<SequenceOperator> convertSource(ParserRuleContext sourceSpecNode, Scope scope) { // DataSources String alias;//from w w w . jav a2s . c om OperatorNode<SequenceOperator> result; ParserRuleContext dataSourceNode = sourceSpecNode; ParserRuleContext aliasContext = null; //data_source //: call_source //| LPAREN source_statement RPAREN //| sequence_source //; if (sourceSpecNode instanceof Source_specContext) { dataSourceNode = (ParserRuleContext) sourceSpecNode.getChild(0); if (sourceSpecNode.getChildCount() == 2) { aliasContext = (ParserRuleContext) sourceSpecNode.getChild(1); } if (dataSourceNode.getChild(0) instanceof Call_sourceContext || dataSourceNode.getChild(0) instanceof Sequence_sourceContext) { dataSourceNode = (ParserRuleContext) dataSourceNode.getChild(0); } //TODO double check whether comment out this is correct // else { //source_statement // dataSourceNode = (ParserRuleContext)dataSourceNode.getChild(1); // } } switch (getParseTreeIndex(dataSourceNode)) { case yqlplusParser.RULE_write_data_source: case yqlplusParser.RULE_call_source: { List<String> names = readName( (Namespaced_nameContext) dataSourceNode.getChild(Namespaced_nameContext.class, 0)); alias = assignAlias(names.get(names.size() - 1), aliasContext, scope); List<OperatorNode<ExpressionOperator>> arguments = ImmutableList.of(); ArgumentsContext argumentsContext = dataSourceNode.getRuleContext(ArgumentsContext.class, 0); if (argumentsContext != null) { List<ArgumentContext> argumentContexts = argumentsContext.argument(); arguments = Lists.newArrayListWithExpectedSize(argumentContexts.size()); for (ArgumentContext argumentContext : argumentContexts) { arguments.add(convertExpr(argumentContext, scope)); } } if (names.size() == 1 && scope.isVariable(names.get(0))) { String ident = names.get(0); if (arguments.size() > 0) { throw new ProgramCompileException(toLocation(scope, argumentsContext), "Invalid call-with-arguments on local source '%s'", ident); } result = OperatorNode.create(toLocation(scope, dataSourceNode), SequenceOperator.EVALUATE, OperatorNode.create(toLocation(scope, dataSourceNode), ExpressionOperator.VARREF, ident)); } else { result = OperatorNode.create(toLocation(scope, dataSourceNode), SequenceOperator.SCAN, scope.resolvePath(names), arguments); } break; } case yqlplusParser.RULE_sequence_source: { IdentContext identContext = dataSourceNode.getRuleContext(IdentContext.class, 0); String ident = identContext.getText(); if (!scope.isVariable(ident)) { throw new ProgramCompileException(toLocation(scope, identContext), "Unknown variable reference '%s'", ident); } alias = assignAlias(ident, aliasContext, scope); result = OperatorNode.create(toLocation(scope, dataSourceNode), SequenceOperator.EVALUATE, OperatorNode.create(toLocation(scope, dataSourceNode), ExpressionOperator.VARREF, ident)); break; } case yqlplusParser.RULE_source_statement: { alias = assignAlias(null, dataSourceNode, scope); result = convertQuery(dataSourceNode, scope); break; } case yqlplusParser.RULE_data_source: { alias = assignAlias("source", aliasContext, scope); result = convertQuery(dataSourceNode.getChild(1), scope); break; } default: throw new IllegalArgumentException( "Unexpected argument type to convertSource: " + dataSourceNode.getText()); } result.putAnnotation("alias", alias); return result; }
From source file:com.yahoo.yqlplus.language.parser.ProgramParser.java
public OperatorNode<ExpressionOperator> convertExpr(ParseTree parseTree, Scope scope) { switch (getParseTreeIndex(parseTree)) { case yqlplusParser.RULE_nullOperator: return OperatorNode.create(ExpressionOperator.NULL); case yqlplusParser.RULE_argument: return convertExpr(parseTree.getChild(0), scope); case yqlplusParser.RULE_fixed_or_parameter: { ParseTree firstChild = parseTree.getChild(0); if (getParseTreeIndex(firstChild) == yqlplusParser.INT) { return OperatorNode.create(toLocation(scope, firstChild), ExpressionOperator.LITERAL, new Integer(firstChild.getText())); } else {//from ww w.ja v a 2 s.c om return convertExpr(firstChild, scope); } } case yqlplusParser.RULE_constantMapExpression: { List<ConstantPropertyNameAndValueContext> propertyList = ((ConstantMapExpressionContext) parseTree) .constantPropertyNameAndValue(); List<String> names = Lists.newArrayListWithExpectedSize(propertyList.size()); List<OperatorNode<ExpressionOperator>> exprs = Lists.newArrayListWithExpectedSize(propertyList.size()); for (ConstantPropertyNameAndValueContext child : propertyList) { // : propertyName ':' expression[$expression::namespace] -> // ^(PROPERTY propertyName expression) names.add(StringUnescaper.unquote(child.getChild(0).getText())); exprs.add(convertExpr(child.getChild(2), scope)); } return OperatorNode.create(toLocation(scope, parseTree), ExpressionOperator.MAP, names, exprs); } case yqlplusParser.RULE_mapExpression: { List<PropertyNameAndValueContext> propertyList = ((MapExpressionContext) parseTree) .propertyNameAndValue(); List<String> names = Lists.newArrayListWithExpectedSize(propertyList.size()); List<OperatorNode<ExpressionOperator>> exprs = Lists.newArrayListWithCapacity(propertyList.size()); for (PropertyNameAndValueContext child : propertyList) { // : propertyName ':' expression[$expression::namespace] -> // ^(PROPERTY propertyName expression) names.add(StringUnescaper.unquote(child.getChild(0).getText())); exprs.add(convertExpr(child.getChild(2), scope)); } return OperatorNode.create(toLocation(scope, parseTree), ExpressionOperator.MAP, names, exprs); } case yqlplusParser.RULE_constantArray: { List<ConstantExpressionContext> expressionList = ((ConstantArrayContext) parseTree) .constantExpression(); List<OperatorNode<ExpressionOperator>> values = Lists .newArrayListWithExpectedSize(expressionList.size()); for (ConstantExpressionContext expr : expressionList) { values.add(convertExpr(expr, scope)); } return OperatorNode.create( toLocation(scope, expressionList.isEmpty() ? parseTree : expressionList.get(0)), ExpressionOperator.ARRAY, values); } case yqlplusParser.RULE_arrayLiteral: { List<ExpressionContext> expressionList = ((ArrayLiteralContext) parseTree).expression(); List<OperatorNode<ExpressionOperator>> values = Lists .newArrayListWithExpectedSize(expressionList.size()); for (ExpressionContext expr : expressionList) { values.add(convertExpr(expr, scope)); } return OperatorNode.create( toLocation(scope, expressionList.isEmpty() ? parseTree : expressionList.get(0)), ExpressionOperator.ARRAY, values); } //dereferencedExpression: primaryExpression(indexref[in_select]| propertyref)* case yqlplusParser.RULE_dereferencedExpression: { DereferencedExpressionContext dereferencedExpression = (DereferencedExpressionContext) parseTree; Iterator<ParseTree> it = dereferencedExpression.children.iterator(); OperatorNode<ExpressionOperator> result = convertExpr(it.next(), scope); while (it.hasNext()) { ParseTree defTree = it.next(); if (getParseTreeIndex(defTree) == yqlplusParser.RULE_propertyref) { //DOT nm=ID result = OperatorNode.create(toLocation(scope, parseTree), ExpressionOperator.PROPREF, result, defTree.getChild(1).getText()); } else { //indexref result = OperatorNode.create(toLocation(scope, parseTree), ExpressionOperator.INDEX, result, convertExpr(defTree.getChild(1), scope)); } } return result; } case yqlplusParser.RULE_primaryExpression: { // ^(CALL namespaced_name arguments) ParseTree firstChild = parseTree.getChild(0); switch (getParseTreeIndex(firstChild)) { case yqlplusParser.RULE_fieldref: { return convertExpr(firstChild, scope); } case yqlplusParser.RULE_callExpresion: { List<ArgumentContext> args = ((ArgumentsContext) firstChild.getChild(1)).argument(); List<OperatorNode<ExpressionOperator>> arguments = Lists.newArrayListWithExpectedSize(args.size()); for (ArgumentContext argContext : args) { arguments.add(convertExpr(argContext.expression(), scope)); } return OperatorNode.create(toLocation(scope, parseTree), ExpressionOperator.CALL, scope.resolvePath(readName((Namespaced_nameContext) firstChild.getChild(0))), arguments); } // TODO add processing this is not implemented in V3 // case yqlplusParser.APPLY: case yqlplusParser.RULE_parameter: // external variable reference return OperatorNode.create(toLocation(scope, firstChild), ExpressionOperator.VARREF, firstChild.getChild(1).getText()); case yqlplusParser.RULE_scalar_literal: case yqlplusParser.RULE_arrayLiteral: case yqlplusParser.RULE_mapExpression: return convertExpr(firstChild, scope); case yqlplusParser.LPAREN: return convertExpr(parseTree.getChild(1), scope); } } // TODO: Temporarily disable CAST - think through how types are named // case yqlplusParser.CAST: { // // return new Cast() // } // return new CastExpression(payload); case yqlplusParser.RULE_parameter: { // external variable reference ParserRuleContext parameterContext = (ParserRuleContext) parseTree; IdentContext identContext = parameterContext.getRuleContext(IdentContext.class, 0); return OperatorNode.create(toLocation(scope, identContext), ExpressionOperator.VARREF, identContext.getText()); } case yqlplusParser.RULE_annotateExpression: { //annotation logicalORExpression AnnotationContext annotateExpressionContext = ((AnnotateExpressionContext) parseTree).annotation(); OperatorNode<ExpressionOperator> annotation = convertExpr( annotateExpressionContext.constantMapExpression(), scope); OperatorNode<ExpressionOperator> expr = convertExpr(parseTree.getChild(1), scope); List<String> names = (List<String>) annotation.getArgument(0); List<OperatorNode<ExpressionOperator>> annotates = (List<OperatorNode<ExpressionOperator>>) annotation .getArgument(1); for (int i = 0; i < names.size(); ++i) { expr.putAnnotation(names.get(i), readConstantExpression(annotates.get(i))); } return expr; } case yqlplusParser.RULE_expression: { return convertExpr(parseTree.getChild(0), scope); } case yqlplusParser.RULE_logicalANDExpression: LogicalANDExpressionContext andExpressionContext = (LogicalANDExpressionContext) parseTree; return readConjOp(ExpressionOperator.AND, andExpressionContext.equalityExpression(), scope); case yqlplusParser.RULE_logicalORExpression: { int childCount = parseTree.getChildCount(); LogicalORExpressionContext logicalORExpressionContext = (LogicalORExpressionContext) parseTree; if (childCount > 1) { return readConjOrOp(ExpressionOperator.OR, logicalORExpressionContext, scope); } else { List<EqualityExpressionContext> equalityExpressionList = ((LogicalANDExpressionContext) parseTree .getChild(0)).equalityExpression(); if (equalityExpressionList.size() > 1) { return readConjOp(ExpressionOperator.AND, equalityExpressionList, scope); } else { return convertExpr(equalityExpressionList.get(0), scope); } } } case yqlplusParser.RULE_equalityExpression: { EqualityExpressionContext equalityExpression = (EqualityExpressionContext) parseTree; RelationalExpressionContext relationalExpressionContext = equalityExpression.relationalExpression(0); OperatorNode<ExpressionOperator> expr = convertExpr(relationalExpressionContext, scope); InNotInTargetContext inNotInTarget = equalityExpression.inNotInTarget(); int childCount = equalityExpression.getChildCount(); if (childCount == 1) { return expr; } if (inNotInTarget != null) { Literal_listContext literalListContext = inNotInTarget.literal_list(); boolean isIN = equalityExpression.IN() != null; if (literalListContext == null) { Select_statementContext selectStatementContext = inNotInTarget.select_statement(); OperatorNode<SequenceOperator> query = convertQuery(selectStatementContext, scope); return OperatorNode.create(expr.getLocation(), isIN ? ExpressionOperator.IN_QUERY : ExpressionOperator.NOT_IN_QUERY, expr, query); } else { // we need to identify the type of the target; if it's a // scalar we need to wrap it in a CREATE_ARRAY // if it's already a CREATE ARRAY then it's fine, otherwise // we need to know the variable type // return readBinOp(node.getType() == yqlplusParser.IN ? // ExpressionOperator.IN : ExpressionOperator.NOT_IN, node, // scope); return readBinOp(isIN ? ExpressionOperator.IN : ExpressionOperator.NOT_IN, equalityExpression.getChild(0), literalListContext, scope); } } else { ParseTree firstChild = equalityExpression.getChild(1); if (equalityExpression.getChildCount() == 2) { switch (getParseTreeIndex(firstChild)) { case yqlplusParser.IS_NULL: return readUnOp(ExpressionOperator.IS_NULL, relationalExpressionContext, scope); case yqlplusParser.IS_NOT_NULL: return readUnOp(ExpressionOperator.IS_NOT_NULL, relationalExpressionContext, scope); } } else { switch (getParseTreeIndex(firstChild.getChild(0))) { case yqlplusParser.EQ: return readBinOp(ExpressionOperator.EQ, equalityExpression.getChild(0), equalityExpression.getChild(2), scope); case yqlplusParser.NEQ: return readBinOp(ExpressionOperator.NEQ, equalityExpression.getChild(0), equalityExpression.getChild(2), scope); case yqlplusParser.LIKE: return readBinOp(ExpressionOperator.LIKE, equalityExpression.getChild(0), equalityExpression.getChild(2), scope); case yqlplusParser.NOTLIKE: return readBinOp(ExpressionOperator.NOT_LIKE, equalityExpression.getChild(0), equalityExpression.getChild(2), scope); case yqlplusParser.MATCHES: return readBinOp(ExpressionOperator.MATCHES, equalityExpression.getChild(0), equalityExpression.getChild(2), scope); case yqlplusParser.NOTMATCHES: return readBinOp(ExpressionOperator.NOT_MATCHES, equalityExpression.getChild(0), equalityExpression.getChild(2), scope); case yqlplusParser.CONTAINS: return readBinOp(ExpressionOperator.CONTAINS, equalityExpression.getChild(0), equalityExpression.getChild(2), scope); } } } break; } case yqlplusParser.RULE_relationalExpression: { RelationalExpressionContext relationalExpressionContext = (RelationalExpressionContext) parseTree; RelationalOpContext opContext = relationalExpressionContext.relationalOp(); if (opContext != null) { switch (getParseTreeIndex(relationalExpressionContext.relationalOp().getChild(0))) { case yqlplusParser.LT: return readBinOp(ExpressionOperator.LT, parseTree, scope); case yqlplusParser.LTEQ: return readBinOp(ExpressionOperator.LTEQ, parseTree, scope); case yqlplusParser.GT: return readBinOp(ExpressionOperator.GT, parseTree, scope); case yqlplusParser.GTEQ: return readBinOp(ExpressionOperator.GTEQ, parseTree, scope); } } else { return convertExpr(relationalExpressionContext.additiveExpression(0), scope); } } break; case yqlplusParser.RULE_additiveExpression: case yqlplusParser.RULE_multiplicativeExpression: { if (parseTree.getChildCount() > 1) { String opStr = parseTree.getChild(1).getText(); switch (opStr) { case "+": return readBinOp(ExpressionOperator.ADD, parseTree, scope); case "-": return readBinOp(ExpressionOperator.SUB, parseTree, scope); case "/": return readBinOp(ExpressionOperator.DIV, parseTree, scope); case "*": return readBinOp(ExpressionOperator.MULT, parseTree, scope); case "%": return readBinOp(ExpressionOperator.MOD, parseTree, scope); default: if (parseTree.getChild(0) instanceof UnaryExpressionContext) { return convertExpr(parseTree.getChild(0), scope); } else { throw new ProgramCompileException(toLocation(scope, parseTree), "Unknown expression type: " + parseTree.toStringTree()); } } } else { if (parseTree.getChild(0) instanceof UnaryExpressionContext) { return convertExpr(parseTree.getChild(0), scope); } else if (parseTree.getChild(0) instanceof MultiplicativeExpressionContext) { return convertExpr(parseTree.getChild(0), scope); } else { throw new ProgramCompileException(toLocation(scope, parseTree), "Unknown expression type: " + parseTree.getText()); } } } case yqlplusParser.RULE_unaryExpression: { if (1 == parseTree.getChildCount()) { return convertExpr(parseTree.getChild(0), scope); } else if (2 == parseTree.getChildCount()) { if ("-".equals(parseTree.getChild(0).getText())) { return readUnOp(ExpressionOperator.NEGATE, parseTree, scope); } else if ("!".equals(parseTree.getChild(0).getText())) { return readUnOp(ExpressionOperator.NOT, parseTree, scope); } throw new ProgramCompileException(toLocation(scope, parseTree), "Unknown unary operator " + parseTree.getText()); } else { throw new ProgramCompileException(toLocation(scope, parseTree), "Unknown child count " + parseTree.getChildCount() + " of " + parseTree.getText()); } } case yqlplusParser.RULE_fieldref: case yqlplusParser.RULE_joinDereferencedExpression: { // all in-scope data sources should be defined in scope // the 'first' field in a namespaced reference must be: // - a field name if (and only if) there is exactly one data source // in scope OR // - an alias name, which will be followed by a field name // ^(FIELDREF<FieldReference>[$expression::namespace] // namespaced_name) List<String> path = readName((Namespaced_nameContext) parseTree.getChild(0)); Location loc = toLocation(scope, parseTree.getChild(0)); String alias = path.get(0); OperatorNode<ExpressionOperator> result; int start; if (scope.isCursor(alias)) { if (path.size() > 1) { result = OperatorNode.create(loc, ExpressionOperator.READ_FIELD, alias, path.get(1)); start = 2; } else { if (scope.getCursors().size() > 1 || Boolean.TRUE.equals(scope.getCursors().get(alias))) { result = OperatorNode.create(loc, ExpressionOperator.READ_RECORD, alias); } else { result = OperatorNode.create(loc, ExpressionOperator.READ_FIELD, alias, alias); } start = 1; } } else if (scope.isBound(alias)) { return OperatorNode.create(loc, ExpressionOperator.READ_MODULE, scope.getBinding(alias).toPathWith(path.subList(1, path.size()))); } else if (scope.getCursors().size() == 1) { alias = scope.getCursors().keySet().iterator().next(); result = OperatorNode.create(loc, ExpressionOperator.READ_FIELD, alias, path.get(0)); start = 1; } else { // ah ha, we can't end up with a 'loose' UDF call because it // won't be a module or known alias // so we need not support implicit imports for constants used in // UDFs throw new ProgramCompileException(loc, "Unknown field or alias '%s'", alias); } for (int idx = start; idx < path.size(); ++idx) { result = OperatorNode.create(loc, ExpressionOperator.PROPREF, result, path.get(idx)); } return result; } case yqlplusParser.RULE_scalar_literal: return OperatorNode.create(toLocation(scope, parseTree), ExpressionOperator.LITERAL, convertLiteral((Scalar_literalContext) parseTree)); case yqlplusParser.RULE_insert_values: return readValues((Insert_valuesContext) parseTree, scope); case yqlplusParser.RULE_constantExpression: return convertExpr(parseTree.getChild(0), scope); case yqlplusParser.RULE_literal_list: List<Literal_elementContext> elements = ((Literal_listContext) parseTree).literal_element(); if (elements.size() == 1) { Literal_elementContext child = elements.get(0); OperatorNode<ExpressionOperator> expr = convertExpr(child.getChild(0), scope); if (expr.getOperator() == ExpressionOperator.VARREF && scope.isArrayArgument((String) expr.getArgument(0))) { return expr; } return OperatorNode.create(toLocation(scope, elements.get(0)), ExpressionOperator.ARRAY, ImmutableList.of(expr)); } List<OperatorNode<ExpressionOperator>> values = Lists.newArrayListWithExpectedSize(elements.size()); for (Literal_elementContext child : elements) { values.add(convertExpr(child.getChild(0), scope)); } return OperatorNode.create(toLocation(scope, elements.get(0)), ExpressionOperator.ARRAY, values); } throw new ProgramCompileException(toLocation(scope, parseTree), "Unknown expression type: " + parseTree.getText()); }