| /******************************************************************************* |
| * Copyright (c) 2006, 2010 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.cdt.core.lrparser.tests; |
| |
| import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator; |
| import org.eclipse.cdt.core.dom.ast.IASTArrayModifier; |
| import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTDeclarator; |
| import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer; |
| import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; |
| import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; |
| import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; |
| import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; |
| import org.eclipse.cdt.core.dom.ast.IASTStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; |
| import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; |
| import org.eclipse.cdt.core.dom.lrparser.gnu.GCCLanguage; |
| import org.eclipse.cdt.core.model.ILanguage; |
| |
| import junit.framework.TestCase; |
| import junit.framework.TestSuite; |
| |
| /** |
| * TODO these tests can be moved into the core |
| */ |
| @SuppressWarnings("nls") |
| public class LRDigraphTrigraphTests extends TestCase { |
| |
| public static TestSuite suite() { |
| return new TestSuite(LRDigraphTrigraphTests.class); |
| } |
| |
| public LRDigraphTrigraphTests() { |
| } |
| |
| public LRDigraphTrigraphTests(String name) { |
| super(name); |
| } |
| |
| protected IASTTranslationUnit parse(String code) { |
| ParseHelper.Options options = new ParseHelper.Options(); |
| options.setCheckSyntaxProblems(true); |
| options.setCheckPreprocessorProblems(true); |
| return ParseHelper.parse(code, getCLanguage(), options); |
| } |
| |
| protected ILanguage getCLanguage() { |
| return GCCLanguage.getDefault(); |
| } |
| |
| public void testTrigraphSequences() { |
| String code = "??=define SIZE ??/ \n" + // trigraph used as backslash to ignore newline |
| "99 \n" + "int main(void)??< \n" + " int arr??(SIZE??); \n" |
| + " arr??(4??) = '0' - (??-0 ??' 1 ??! 2); \n" + " printf(\"%c??/n\", arr??(4??)); \n" |
| + "??> \n"; |
| |
| IASTTranslationUnit tu = parse(code); |
| assertNotNull(tu); |
| |
| IASTPreprocessorStatement[] defines = tu.getAllPreprocessorStatements(); |
| assertEquals(1, defines.length); |
| IASTPreprocessorMacroDefinition macro = (IASTPreprocessorMacroDefinition) defines[0]; |
| assertEquals("SIZE", macro.getName().toString()); |
| //assertEquals("99", macro.getExpansion()); |
| |
| IASTFunctionDefinition main = (IASTFunctionDefinition) tu.getDeclarations()[0]; |
| IASTCompoundStatement body = (IASTCompoundStatement) main.getBody(); |
| IASTStatement[] statements = body.getStatements(); |
| assertEquals(3, statements.length); |
| |
| // int arr??(SIZE??); |
| IASTSimpleDeclaration arr = (IASTSimpleDeclaration) ((IASTDeclarationStatement) statements[0]).getDeclaration(); |
| IASTArrayDeclarator arr_decl = (IASTArrayDeclarator) arr.getDeclarators()[0]; |
| IASTArrayModifier modifier = arr_decl.getArrayModifiers()[0]; |
| IASTLiteralExpression lit = (IASTLiteralExpression) modifier.getConstantExpression(); |
| assertEquals(IASTLiteralExpression.lk_integer_constant, lit.getKind()); |
| |
| // arr??(4??) = '0' - (??-0 ??' 1 ??! 2); |
| IASTBinaryExpression expr = (IASTBinaryExpression) ((IASTExpressionStatement) statements[1]).getExpression(); |
| assertEquals(IASTBinaryExpression.op_assign, expr.getOperator()); |
| IASTArraySubscriptExpression arr_op = (IASTArraySubscriptExpression) expr.getOperand1(); |
| assertEquals("4", ((IASTLiteralExpression) arr_op.getSubscriptExpression()).toString()); |
| IASTBinaryExpression cond = (IASTBinaryExpression) ((IASTUnaryExpression) ((IASTBinaryExpression) expr |
| .getOperand2()).getOperand2()).getOperand(); |
| assertEquals(IASTBinaryExpression.op_binaryOr, cond.getOperator()); |
| IASTBinaryExpression cond2 = (IASTBinaryExpression) cond.getOperand1(); |
| assertEquals(IASTBinaryExpression.op_binaryXor, cond2.getOperator()); |
| IASTUnaryExpression not = (IASTUnaryExpression) cond2.getOperand1(); |
| assertEquals(IASTUnaryExpression.op_tilde, not.getOperator()); |
| |
| // printf(\"%c??/n\", arr??(4??)); |
| IASTFunctionCallExpression expr2 = (IASTFunctionCallExpression) ((IASTExpressionStatement) statements[2]) |
| .getExpression(); |
| IASTInitializerClause[] args = expr2.getArguments(); |
| IASTArraySubscriptExpression arr_op2 = (IASTArraySubscriptExpression) args[1]; |
| assertEquals("4", ((IASTLiteralExpression) arr_op2.getSubscriptExpression()).toString()); |
| } |
| |
| public void testTrigraphEscapeSequences() { |
| // a ??/ trigraph should act just like a backslash in a string literal |
| String code = "int main(void)??< \n" + " char str[] = \"??/\"??/n\"; \n" + " char c = '??/u0000'; \n" |
| + "??> \n"; |
| |
| parse(code); // will throw an exception if there are parse errors |
| } |
| |
| public void testDigraphSequences() { |
| String code = "%:define join(a, b) a %:%: b \n" + "int main() <% \n" + " int arr<:5:>; \n" + "%> \n"; |
| |
| IASTTranslationUnit tu = parse(code); // will throw an exception if there are parse errors |
| |
| IASTFunctionDefinition main = (IASTFunctionDefinition) tu.getDeclarations()[0]; |
| IASTCompoundStatement body = (IASTCompoundStatement) main.getBody(); |
| IASTStatement[] statements = body.getStatements(); |
| assertEquals(1, statements.length); |
| |
| IASTSimpleDeclaration arr = (IASTSimpleDeclaration) ((IASTDeclarationStatement) statements[0]).getDeclaration(); |
| IASTArrayDeclarator arr_decl = (IASTArrayDeclarator) arr.getDeclarators()[0]; |
| IASTArrayModifier modifier = arr_decl.getArrayModifiers()[0]; |
| IASTLiteralExpression lit = (IASTLiteralExpression) modifier.getConstantExpression(); |
| assertEquals("5", lit.toString()); |
| |
| } |
| |
| public void testTrigraphAndDigraphSequecesInPreprocessorDirectives() { |
| String code = "%:define join1(a, b) a %:%: b \n" + "%:define str1(a) %: a \n" |
| + "??=define join2(a, b) a ??=??= b \n" + "??=define str2(a) ??= a \n" + "int main() <% \n" |
| + " int join1(x, y) = str1(its all good); \n" + " int join2(a, b) = str2(its still good); \n" |
| + "%> \n"; |
| |
| IASTTranslationUnit tu = parse(code); // will throw an exception if there are parse errors |
| |
| IASTFunctionDefinition main = (IASTFunctionDefinition) tu.getDeclarations()[0]; |
| IASTCompoundStatement body = (IASTCompoundStatement) main.getBody(); |
| IASTStatement[] statements = body.getStatements(); |
| assertEquals(2, statements.length); |
| |
| IASTSimpleDeclaration decl1 = (IASTSimpleDeclaration) ((IASTDeclarationStatement) statements[0]) |
| .getDeclaration(); |
| IASTDeclarator declarator1 = decl1.getDeclarators()[0]; |
| assertEquals("xy", declarator1.getName().toString()); |
| IASTLiteralExpression expr1 = (IASTLiteralExpression) ((IASTEqualsInitializer) declarator1.getInitializer()) |
| .getInitializerClause(); |
| assertEquals(IASTLiteralExpression.lk_string_literal, expr1.getKind()); |
| assertEquals("\"its all good\"", expr1.toString()); |
| |
| IASTSimpleDeclaration decl2 = (IASTSimpleDeclaration) ((IASTDeclarationStatement) statements[1]) |
| .getDeclaration(); |
| IASTDeclarator declarator2 = decl2.getDeclarators()[0]; |
| assertEquals("ab", declarator2.getName().toString()); |
| IASTLiteralExpression expr2 = (IASTLiteralExpression) ((IASTEqualsInitializer) declarator2.getInitializer()) |
| .getInitializerClause(); |
| assertEquals(IASTLiteralExpression.lk_string_literal, expr2.getKind()); |
| assertEquals("\"its still good\"", expr2.toString()); |
| } |
| } |