From 0900e0040e90965f9529a51a681880cb5b644a09 Mon Sep 17 00:00:00 2001 From: "JesusFreke@JesusFreke.com" Date: Fri, 5 Jun 2009 05:14:26 +0000 Subject: [PATCH] - Added support for specifying a char literal for various types of instruction - Fixed a bug preventing the usage of negative float/double literals - Fixed escape sequences in character literals - Added source file name to parser error messages - Fixed an issue where the parser would exit without an error message, when it encountered a bad "top level" token (in the smali_file rule) - Fixed an issue that prevented the usage of non long/double literals with the the const-wide instruction - Fixed an issue with the invoke-static/range, where it wouldn't calculate the number of parameter registers correctly, and would erroneously generate an error message git-svn-id: https://smali.googlecode.com/svn/trunk@90 55b6fa8a-2a1e-11de-a435-ffa8d773f76a --- .../antlr3/org/JesusFreke/smali/smaliLexer.g | 24 ++++++++++++------- .../antlr3/org/JesusFreke/smali/smaliParser.g | 13 +++++++--- .../org/JesusFreke/smali/smaliTreeWalker.g | 1 + .../dexlib/code/Format/Format3rc.java | 2 +- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g b/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g index 1ba2731d..21995306 100644 --- a/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g +++ b/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g @@ -811,6 +811,7 @@ fragment INTEGRAL_LITERAL_EMITCHILD : LONG_LITERAL_EMIT | INTEGER_LITERAL_EMIT | SHORT_LITERAL_EMIT + | CHAR_LITERAL_EMIT | BYTE_LITERAL_EMIT; fragment FIXED_LITERAL_EMITCHILD @@ -1020,23 +1021,28 @@ fragment BINARY_EXPONENT fragment FLOAT_LITERAL_EMIT : FLOAT_LITERAL {emit($FLOAT_LITERAL, FLOAT_LITERAL);}; fragment FLOAT_LITERAL - : (FLOATING_POINT_NUMBER | ('0' .. '9')+) ('f' | 'F'); + : '-'? (FLOATING_POINT_NUMBER | ('0' .. '9')+) ('f' | 'F'); fragment DOUBLE_LITERAL_EMIT : DOUBLE_LITERAL {emit($DOUBLE_LITERAL, DOUBLE_LITERAL);}; fragment DOUBLE_LITERAL - : FLOATING_POINT_NUMBER ('d' | 'D')? - | ('0' .. '9')+ ('d' | 'D'); + : '-'? FLOATING_POINT_NUMBER ('d' | 'D')? + | '-'? ('0' .. '9')+ ('d' | 'D'); fragment CHAR_LITERAL_EMIT - : CHAR_LITERAL {emit($CHAR_LITERAL, CHAR_LITERAL);}; -fragment CHAR_LITERAL - : '\'' {StringBuilder sb = new StringBuilder("'");} - ( ESCAPE_SEQUENCE[sb] {sb.append("'"); setText(sb.toString());} - | ~( '\'' | '\\' | '\r' | '\n' ) + @init {StringBuilder sb = new StringBuilder();} + : CHAR_LITERAL[sb] + { + $CHAR_LITERAL.setText(sb.toString()); + emit($CHAR_LITERAL, CHAR_LITERAL); + }; +fragment CHAR_LITERAL[StringBuilder sb] + : '\'' {sb.append("'");} + ( ESCAPE_SEQUENCE[sb] {sb.append("'");} + | ~( '\'' | '\\' | '\r' | '\n' ) {sb.append((char)input.LA(-1));} ) - '\'' + '\'' {sb.append("'");} ; fragment BOOL_LITERAL_EMIT diff --git a/src/main/antlr3/org/JesusFreke/smali/smaliParser.g b/src/main/antlr3/org/JesusFreke/smali/smaliParser.g index 316d5fcc..62c8bb28 100644 --- a/src/main/antlr3/org/JesusFreke/smali/smaliParser.g +++ b/src/main/antlr3/org/JesusFreke/smali/smaliParser.g @@ -147,6 +147,10 @@ import org.JesusFreke.dexlib.code.Format.*; public String getTokenErrorDisplay(Token t) { return t.toString(); } + + public String getErrorHeader(RecognitionException e) { + return getSourceName()+"["+ e.line+","+e.charPositionInLine+"]"; + } } @@ -165,7 +169,9 @@ smali_file | {!$smali_file::hasSourceSpec}?=> source_spec {$smali_file::hasSourceSpec = true;} | method | field - | annotation)* + | annotation + )+ + EOF { if (!$smali_file::hasClassSpec) { //TODO: throw correct exception type @@ -394,8 +400,8 @@ instruction returns [int size] INSTRUCTION_FORMAT3rc_METHOD OPEN_BRACKET register_range CLOSE_BRACKET fully_qualified_method {$size = Format3rc.Format.getByteCount();} -> ^(I_STATEMENT_FORMAT3rc_METHOD[$start, "I_STATEMENT_FORMAT3rc_METHOD"] INSTRUCTION_FORMAT3rc_METHOD register_range fully_qualified_method) | //e.g. const-wide v0, 5000000000L - INSTRUCTION_FORMAT51l REGISTER (LONG_LITERAL | DOUBLE_LITERAL) {$size = Format51l.Format.getByteCount();} - -> ^(I_STATEMENT_FORMAT51l[$start, "I_STATEMENT_FORMAT51l"] INSTRUCTION_FORMAT51l REGISTER LONG_LITERAL? DOUBLE_LITERAL?) + INSTRUCTION_FORMAT51l REGISTER fixed_literal {$size = Format51l.Format.getByteCount();} + -> ^(I_STATEMENT_FORMAT51l[$start, "I_STATEMENT_FORMAT51l"] INSTRUCTION_FORMAT51l REGISTER fixed_literal) | ARRAY_DATA_DIRECTIVE { @@ -513,6 +519,7 @@ integral_literal : LONG_LITERAL | INTEGER_LITERAL | SHORT_LITERAL + | CHAR_LITERAL | BYTE_LITERAL; fixed_32bit_literal diff --git a/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g b/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g index 09634251..9fedc9d7 100644 --- a/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g +++ b/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g @@ -1076,6 +1076,7 @@ short_integral_literal returns[short value] $value = (short)$integer_literal.value; } | short_literal {$value = $short_literal.value;} + | char_literal {$value = (short)$char_literal.value;} | byte_literal {$value = $byte_literal.value;}; integral_literal returns[int value] diff --git a/src/main/java/org/JesusFreke/dexlib/code/Format/Format3rc.java b/src/main/java/org/JesusFreke/dexlib/code/Format/Format3rc.java index e41875cf..7bdcd9b9 100644 --- a/src/main/java/org/JesusFreke/dexlib/code/Format/Format3rc.java +++ b/src/main/java/org/JesusFreke/dexlib/code/Format/Format3rc.java @@ -82,7 +82,7 @@ public class Format3rc extends Format } else if (opcode >= INVOKE_VIRTUAL_RANGE.value && opcode <= INVOKE_INTERFACE_RANGE.value) { //check data for invoke-*/range opcodes MethodIdItem methodIdItem = (MethodIdItem)item; - if (methodIdItem.getParameterRegisterCount(opcode == INVOKE_STATIC.value) != regCount) { + if (methodIdItem.getParameterRegisterCount(opcode == INVOKE_STATIC_RANGE.value) != regCount) { throw new RuntimeException("regCount does not match the number of arguments of the method"); } } else {