package buntatsun.cdt.proc; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement; import org.eclipse.cdt.core.dom.ast.IASTLabelStatement; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.parser.c.ICParserExtensionConfiguration; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.parser.EndOfFileException; import org.eclipse.cdt.core.parser.IParserLogService; import org.eclipse.cdt.core.parser.IScanner; import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.BacktrackException; import org.eclipse.cdt.internal.core.dom.parser.DeclarationOptions; import org.eclipse.cdt.internal.core.dom.parser.c.CASTFunctionCallExpression; import org.eclipse.cdt.internal.core.dom.parser.c.GNUCSourceParser; @SuppressWarnings("restriction") public class ProCSourceParser extends GNUCSourceParser { public ProCSourceParser(IScanner scanner, ParserMode parserMode, IParserLogService logService, ICParserExtensionConfiguration config) { this(scanner, parserMode, logService, config, null); } public ProCSourceParser(IScanner scanner, ParserMode parserMode, IParserLogService logService, ICParserExtensionConfiguration config, IIndex index) { super(scanner, parserMode, logService, config, index); } @Override protected IASTStatement statement() throws EndOfFileException, BacktrackException { switch (LT(1)) { case IProCToken.tEXEC: switch (LT(2)) { case IProCToken.tSQL: case IProCToken.tORACLE: case IProCToken.tTOOLS: case IProCToken.tIAF: /* * Pro*C */ return parseSqlStatement(); } } return super.statement(); } /* * Pro*C */ protected IASTStatement parseSqlStatement() throws EndOfFileException, BacktrackException { final IToken t1 = consume(); IASTStatement stmt = getNodeFactory().newCompoundStatement(); int endOfProc = IToken.tSEMI; IToken t = t1; while (true) { final int type = t.getType(); switch (type) { case IProCToken.tEXECUTE: switch (LT(1)) { case IProCToken.tDECLARE: case IProCToken.tBEGIN: endOfProc = IProCToken.tEND_EXEC; break; } break; } if (type == IToken.tIDENTIFIER || type >= IProCToken.FIRST_IProCToken) { /* * Pro*C keyword */ final int offset = t.getOffset(); final int endOffset = t.getEndOffset(); final int length = t.getLength(); IASTName name = getNodeFactory().newName(t.getCharImage()); ((ASTNode) name).setOffsetAndLength(offset, length); IBinding binding = new ProCBinding(name); name.setBinding(binding); ProCNullStatement null_statement = new ProCNullStatement(name); setRange(null_statement, offset, endOffset); null_statement.setParent(stmt); ((IASTCompoundStatement) stmt).addStatement(null_statement); } if (type == endOfProc) { break; } for (int loop = 0; LT(1) == IToken.tCOLON && loop < 2; loop++) { /* * Pro*C host & indicator variable. -> fake ++ expression. * 1st loop : host variable * 2nd loop : indicator variable */ LA(1).setType(IToken.tINCR); IASTExpression expression = unaryExpression(IASTUnaryExpression.op_prefixIncr, CastExprCtx.eDirectlyInBExpr, null); // ignore "bar" of ":foo(bar)" IASTNode[] nodes = expression.getChildren(); for (int i = 0; i < nodes.length; i++) { if (nodes[i] instanceof CASTFunctionCallExpression) { CASTFunctionCallExpression fc = (CASTFunctionCallExpression) nodes[i]; fc.setArguments(null); } } IASTExpressionStatement expressionStatement = getNodeFactory().newExpressionStatement(expression); setRange(expressionStatement, expression); expressionStatement.setParent(stmt); ((IASTCompoundStatement) stmt).addStatement(expressionStatement); } t = consume(); } if (stmt == null) { stmt = getNodeFactory().newNullStatement(); } ((ASTNode) stmt).setOffsetAndLength(t1.getOffset(), t.getEndOffset() - t1.getOffset()); return stmt; } @Override protected IASTDeclaration[] problemDeclaration(int offset, BacktrackException bt, DeclarationOptions option) { try { switch (LT(1)) { case IProCToken.tEXEC: switch (LT(2)) { case IProCToken.tSQL: case IProCToken.tORACLE: case IProCToken.tTOOLS: case IProCToken.tIAF: IASTStatement stmt = getNodeFactory().newCompoundStatement(); // skip to semicolon or END-EXEC int endOfProc = IToken.tSEMI; IToken t = consume(); while (true) { switch (t.getType()) { case IProCToken.tEXECUTE: switch (LT(1)) { case IProCToken.tDECLARE: case IProCToken.tBEGIN: endOfProc = IProCToken.tEND_EXEC; break; } break; } final int type = t.getType(); if (type == IToken.tIDENTIFIER || type >= IProCToken.FIRST_IProCToken) { final int p_offset = t.getOffset(); final int p_endOffset = t.getEndOffset(); final int p_length = t.getLength(); IASTName name = getNodeFactory().newName(t.getCharImage()); ((ASTNode) name).setOffsetAndLength(p_offset, p_length); IBinding binding = new ProCBinding(name); name.setBinding(binding); IASTLabelStatement label_statement = getNodeFactory().newLabelStatement(name, null); setRange(label_statement, p_offset, p_endOffset); label_statement.setParent(stmt); ((IASTCompoundStatement) stmt).addStatement(label_statement); } if (type == endOfProc) { break; } t = consume(); } return new IASTDeclaration[] {}; } } } catch (EndOfFileException e) { return new IASTDeclaration[] {}; } return super.problemDeclaration(offset, bt, option); } }