- 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
This commit is contained in:
JesusFreke@JesusFreke.com 2009-06-05 05:14:26 +00:00
parent 5dc3a8d75a
commit 0900e0040e
4 changed files with 27 additions and 13 deletions

View File

@ -811,6 +811,7 @@ fragment INTEGRAL_LITERAL_EMITCHILD
: LONG_LITERAL_EMIT : LONG_LITERAL_EMIT
| INTEGER_LITERAL_EMIT | INTEGER_LITERAL_EMIT
| SHORT_LITERAL_EMIT | SHORT_LITERAL_EMIT
| CHAR_LITERAL_EMIT
| BYTE_LITERAL_EMIT; | BYTE_LITERAL_EMIT;
fragment FIXED_LITERAL_EMITCHILD fragment FIXED_LITERAL_EMITCHILD
@ -1020,23 +1021,28 @@ fragment BINARY_EXPONENT
fragment FLOAT_LITERAL_EMIT fragment FLOAT_LITERAL_EMIT
: FLOAT_LITERAL {emit($FLOAT_LITERAL, FLOAT_LITERAL);}; : FLOAT_LITERAL {emit($FLOAT_LITERAL, FLOAT_LITERAL);};
fragment FLOAT_LITERAL fragment FLOAT_LITERAL
: (FLOATING_POINT_NUMBER | ('0' .. '9')+) ('f' | 'F'); : '-'? (FLOATING_POINT_NUMBER | ('0' .. '9')+) ('f' | 'F');
fragment DOUBLE_LITERAL_EMIT fragment DOUBLE_LITERAL_EMIT
: DOUBLE_LITERAL {emit($DOUBLE_LITERAL, DOUBLE_LITERAL);}; : DOUBLE_LITERAL {emit($DOUBLE_LITERAL, DOUBLE_LITERAL);};
fragment DOUBLE_LITERAL fragment DOUBLE_LITERAL
: FLOATING_POINT_NUMBER ('d' | 'D')? : '-'? FLOATING_POINT_NUMBER ('d' | 'D')?
| ('0' .. '9')+ ('d' | 'D'); | '-'? ('0' .. '9')+ ('d' | 'D');
fragment CHAR_LITERAL_EMIT fragment CHAR_LITERAL_EMIT
: CHAR_LITERAL {emit($CHAR_LITERAL, CHAR_LITERAL);}; @init {StringBuilder sb = new StringBuilder();}
fragment CHAR_LITERAL : CHAR_LITERAL[sb]
: '\'' {StringBuilder sb = new StringBuilder("'");} {
( ESCAPE_SEQUENCE[sb] {sb.append("'"); setText(sb.toString());} $CHAR_LITERAL.setText(sb.toString());
| ~( '\'' | '\\' | '\r' | '\n' ) 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 fragment BOOL_LITERAL_EMIT

View File

@ -147,6 +147,10 @@ import org.JesusFreke.dexlib.code.Format.*;
public String getTokenErrorDisplay(Token t) { public String getTokenErrorDisplay(Token t) {
return t.toString(); 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;} | {!$smali_file::hasSourceSpec}?=> source_spec {$smali_file::hasSourceSpec = true;}
| method | method
| field | field
| annotation)* | annotation
)+
EOF
{ {
if (!$smali_file::hasClassSpec) { if (!$smali_file::hasClassSpec) {
//TODO: throw correct exception type //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();} 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) -> ^(I_STATEMENT_FORMAT3rc_METHOD[$start, "I_STATEMENT_FORMAT3rc_METHOD"] INSTRUCTION_FORMAT3rc_METHOD register_range fully_qualified_method)
| //e.g. const-wide v0, 5000000000L | //e.g. const-wide v0, 5000000000L
INSTRUCTION_FORMAT51l REGISTER (LONG_LITERAL | DOUBLE_LITERAL) {$size = Format51l.Format.getByteCount();} INSTRUCTION_FORMAT51l REGISTER fixed_literal {$size = Format51l.Format.getByteCount();}
-> ^(I_STATEMENT_FORMAT51l[$start, "I_STATEMENT_FORMAT51l"] INSTRUCTION_FORMAT51l REGISTER LONG_LITERAL? DOUBLE_LITERAL?) -> ^(I_STATEMENT_FORMAT51l[$start, "I_STATEMENT_FORMAT51l"] INSTRUCTION_FORMAT51l REGISTER fixed_literal)
| |
ARRAY_DATA_DIRECTIVE ARRAY_DATA_DIRECTIVE
{ {
@ -513,6 +519,7 @@ integral_literal
: LONG_LITERAL : LONG_LITERAL
| INTEGER_LITERAL | INTEGER_LITERAL
| SHORT_LITERAL | SHORT_LITERAL
| CHAR_LITERAL
| BYTE_LITERAL; | BYTE_LITERAL;
fixed_32bit_literal fixed_32bit_literal

View File

@ -1076,6 +1076,7 @@ short_integral_literal returns[short value]
$value = (short)$integer_literal.value; $value = (short)$integer_literal.value;
} }
| short_literal {$value = $short_literal.value;} | short_literal {$value = $short_literal.value;}
| char_literal {$value = (short)$char_literal.value;}
| byte_literal {$value = $byte_literal.value;}; | byte_literal {$value = $byte_literal.value;};
integral_literal returns[int value] integral_literal returns[int value]

View File

@ -82,7 +82,7 @@ public class Format3rc extends Format
} else if (opcode >= INVOKE_VIRTUAL_RANGE.value && opcode <= INVOKE_INTERFACE_RANGE.value) { } else if (opcode >= INVOKE_VIRTUAL_RANGE.value && opcode <= INVOKE_INTERFACE_RANGE.value) {
//check data for invoke-*/range opcodes //check data for invoke-*/range opcodes
MethodIdItem methodIdItem = (MethodIdItem)item; 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"); throw new RuntimeException("regCount does not match the number of arguments of the method");
} }
} else { } else {