From 0f597ae106b77dfe03b6e66b40a4de554304d5b6 Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Thu, 26 Feb 2015 20:01:58 -0800 Subject: [PATCH] Add better error recovery for open/close braces --- smalidea/src/main/antlr3/smalideaParser.g | 26 +++++++-- .../test/java/org/jf/smalidea/ParserTest.java | 1 + smalidea/testData/InvalidInstruction.smalidea | 4 ++ smalidea/testData/InvalidInstruction.txt | 54 +++++++++++++++++++ 4 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 smalidea/testData/InvalidInstruction.smalidea create mode 100644 smalidea/testData/InvalidInstruction.txt diff --git a/smalidea/src/main/antlr3/smalideaParser.g b/smalidea/src/main/antlr3/smalideaParser.g index 25713520..a400da2f 100644 --- a/smalidea/src/main/antlr3/smalideaParser.g +++ b/smalidea/src/main/antlr3/smalideaParser.g @@ -452,6 +452,22 @@ close_paren reportError(errorMarker, re, false); } +open_brace + : OPEN_BRACE; + catch [RecognitionException re] { + Marker errorMarker = mark(); + recover(input, re); + reportError(errorMarker, re, false); + } + +close_brace + : CLOSE_BRACE; + catch [RecognitionException re] { + Marker errorMarker = mark(); + recover(input, re); + reportError(errorMarker, re, false); + } + param_list_inner : ((PARAM_LIST_START param* PARAM_LIST_END) | (PARAM_LIST_OR_ID_START param* PARAM_LIST_OR_ID_END) @@ -656,7 +672,7 @@ string_literal array_literal @init { Marker marker = mark(); } - : OPEN_BRACE (literal (COMMA literal)* | ) CLOSE_BRACE + : open_brace (literal (COMMA literal)* | ) close_brace { marker.done(SmaliElementTypes.LITERAL); }; catch [RecognitionException re] { recover(input, re); @@ -868,17 +884,17 @@ label_ref } register_list - : OPEN_BRACE (register (COMMA register)*)? CLOSE_BRACE; + : open_brace (register (COMMA register)*)? close_brace; register_range - : OPEN_BRACE (register (DOTDOT register)?)? CLOSE_BRACE; + : open_brace (register (DOTDOT register)?)? close_brace; verification_error_reference : class_descriptor | fully_qualified_field | fully_qualified_method; catch_directive @init { Marker marker = mark(); } - : CATCH_DIRECTIVE nonvoid_type_descriptor OPEN_BRACE label_ref DOTDOT label_ref CLOSE_BRACE label_ref + : CATCH_DIRECTIVE nonvoid_type_descriptor open_brace label_ref DOTDOT label_ref close_brace label_ref { marker.done(SmaliElementTypes.CATCH_STATEMENT); }; catch [RecognitionException re] { recover(input, re); @@ -887,7 +903,7 @@ catch_directive catchall_directive @init { Marker marker = mark(); } - : CATCHALL_DIRECTIVE OPEN_BRACE label_ref DOTDOT label_ref CLOSE_BRACE label_ref + : CATCHALL_DIRECTIVE open_brace label_ref DOTDOT label_ref close_brace label_ref { marker.done(SmaliElementTypes.CATCH_ALL_STATEMENT); }; catch [RecognitionException re] { recover(input, re); diff --git a/smalidea/src/test/java/org/jf/smalidea/ParserTest.java b/smalidea/src/test/java/org/jf/smalidea/ParserTest.java index 4bcfdfd2..7610874a 100644 --- a/smalidea/src/test/java/org/jf/smalidea/ParserTest.java +++ b/smalidea/src/test/java/org/jf/smalidea/ParserTest.java @@ -51,6 +51,7 @@ public class ParserTest extends LightCodeInsightParsingTestCase { public void testInvalidField2() throws Exception { doTest(true); } public void testInvalidField3() throws Exception { doTest(true); } public void testInvalidField4() throws Exception { doTest(true); } + public void testInvalidInstruction() throws Exception { doTest(true); } public void testParamListInvalidParameter() throws Exception { doTest(true); } public void testSuperClassInvalidSyntax() throws Exception { doTest(true); } public void testSuperClassInvalidSyntax2() throws Exception { doTest(true); } diff --git a/smalidea/testData/InvalidInstruction.smalidea b/smalidea/testData/InvalidInstruction.smalidea new file mode 100644 index 00000000..94d19f58 --- /dev/null +++ b/smalidea/testData/InvalidInstruction.smalidea @@ -0,0 +1,4 @@ +.method blah()V +.registers 1 +invoke-virtual .blah v0}, Lblah;->blah()V +.end method \ No newline at end of file diff --git a/smalidea/testData/InvalidInstruction.txt b/smalidea/testData/InvalidInstruction.txt new file mode 100644 index 00000000..c152a942 --- /dev/null +++ b/smalidea/testData/InvalidInstruction.txt @@ -0,0 +1,54 @@ +smali.FILE + SmaliClass(CLASS) + SmaliExtendsList(EXTENDS_LIST) + + SmaliImplementsList(IMPLEMENTS_LIST) + + SmaliMethod(METHOD) + SmaliThrowsList(THROWS_LIST) + + PsiElement(METHOD_DIRECTIVE)('.method') + PsiWhiteSpace(' ') + SmaliModifierList(MODIFIER_LIST) + + PsiElement(MEMBER_NAME) + PsiElement(SIMPLE_NAME)('blah') + SmaliMethodPrototype(METHOD_PROTOTYPE) + PsiElement(OPEN_PAREN)('(') + SmaliMethodParamList(METHOD_PARAM_LIST) + + PsiElement(CLOSE_PAREN)(')') + PsiElement(VOID_TYPE) + PsiElement(VOID_TYPE)('V') + PsiWhiteSpace('\n') + PsiElement(REGISTERS_STATEMENT) + PsiElement(REGISTERS_DIRECTIVE)('.registers') + PsiWhiteSpace(' ') + PsiElement(LITERAL) + PsiElement(POSITIVE_INTEGER_LITERAL)('1') + PsiWhiteSpace('\n') + PsiElement(INSTRUCTION) + PsiElement(INSTRUCTION_FORMAT35c_METHOD)('invoke-virtual') + PsiWhiteSpace(' ') + PsiErrorElement:mismatched input '.blah' expecting OPEN_BRACE + PsiElement(BAD_CHARACTER)('.blah') + PsiWhiteSpace(' ') + PsiElement(REGISTER_REFERENCE) + PsiElement(REGISTER)('v0') + PsiElement(CLOSE_BRACE)('}') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + PsiElement(METHOD_REFERENCE) + PsiElement(CLASS_TYPE) + PsiElement(CLASS_DESCRIPTOR)('Lblah;') + PsiElement(ARROW)('->') + PsiElement(MEMBER_NAME) + PsiElement(SIMPLE_NAME)('blah') + PsiElement(OPEN_PAREN)('(') + PsiElement(METHOD_REFERENCE_PARAM_LIST) + + PsiElement(CLOSE_PAREN)(')') + PsiElement(VOID_TYPE) + PsiElement(VOID_TYPE)('V') + PsiWhiteSpace('\n') + PsiElement(END_METHOD_DIRECTIVE)('.end method') \ No newline at end of file