diff --git a/smalidea/src/main/antlr3/smalideaParser.g b/smalidea/src/main/antlr3/smalideaParser.g index 7eec730b..8d04fbb9 100644 --- a/smalidea/src/main/antlr3/smalideaParser.g +++ b/smalidea/src/main/antlr3/smalideaParser.g @@ -209,7 +209,7 @@ smali_file class_spec @init { Marker marker = mark(); } - : CLASS_DIRECTIVE access_list class_descriptor + : CLASS_DIRECTIVE class_access_list class_descriptor { marker.done(SmaliElementTypes.CLASS_STATEMENT); }; catch [RecognitionException re] { recover(input, re); @@ -243,6 +243,18 @@ source_spec reportError(marker, re, false); } +// class_access_list should be separate from access_list, because +// it exists in a slightly different context, and can consume +// ACCESS_SPECs greedily, without having to look ahead. +class_access_list + @init { Marker marker = mark(); } + : ACCESS_SPEC* + { marker.done(SmaliElementTypes.ACCESS_LIST); }; + catch [RecognitionException re] { + recover(input, re); + reportError(marker, re, false); + } + access_list @init { Marker marker = mark(); } : ACCESS_SPEC* diff --git a/smalidea/src/test/java/org/jf/smalidea/ParserTest.java b/smalidea/src/test/java/org/jf/smalidea/ParserTest.java index 16d444b4..6af83c02 100644 --- a/smalidea/src/test/java/org/jf/smalidea/ParserTest.java +++ b/smalidea/src/test/java/org/jf/smalidea/ParserTest.java @@ -98,6 +98,7 @@ public class ParserTest extends ParsingTestCase { public void testEmpty() throws Exception { doTest(true); } public void testInvalidClassDirective() throws Exception { doTest(true); } public void testInvalidClassDirective2() throws Exception { doTest(true); } + public void testInvalidClassDirective3() 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/InvalidClassDirective3.smalidea b/smalidea/testData/InvalidClassDirective3.smalidea new file mode 100644 index 00000000..fd5d3608 --- /dev/null +++ b/smalidea/testData/InvalidClassDirective3.smalidea @@ -0,0 +1 @@ +.class public .class Ltest; \ No newline at end of file diff --git a/smalidea/testData/InvalidClassDirective3.txt b/smalidea/testData/InvalidClassDirective3.txt new file mode 100644 index 00000000..06b7184b --- /dev/null +++ b/smalidea/testData/InvalidClassDirective3.txt @@ -0,0 +1,18 @@ +smali.FILE + SmaliClass(CLASS) + SmaliModifierList(MODIFIER_LIST) + + SmaliExtendsList(EXTENDS_LIST) + + SmaliImplementsList(IMPLEMENTS_LIST) + + PsiElement(CLASS_STATEMENT) + PsiElement(CLASS_DIRECTIVE)('.class') + PsiWhiteSpace(' ') + PsiElement(ACCESS_LIST) + PsiElement(ACCESS_SPEC)('public') + PsiWhiteSpace(' ') + PsiErrorElement:extraneous input '.class' expecting CLASS_DESCRIPTOR + PsiElement(CLASS_DIRECTIVE)('.class') + PsiWhiteSpace(' ') + PsiElement(CLASS_DESCRIPTOR)('Ltest;') \ No newline at end of file