Add support for more statements

* If statements decompiled correctly
    * Unary expressions have neater decompilation
    * Break and continue statements
    * Comparison operators decompiled correctly
This commit is contained in:
Dhruv Maroo
2023-04-26 23:50:32 +05:30
parent 3095de7bbd
commit 61d0e9b94a
11 changed files with 699 additions and 515 deletions

View File

@@ -277,7 +277,11 @@ public class CVisitor implements CParserVisitor {
} }
public Object visit(ASTSelectionStatement node, Object data) { public Object visit(ASTSelectionStatement node, Object data) {
return defaultVisit(node, data); StringBuilder ret = new StringBuilder(
"if (" + node.jjtGetChild(0).jjtAccept(this, data) + ") {" + node.jjtGetChild(1).jjtAccept(this, data));
ret.append("}");
((CContext) data).statement_end_sc = false;
return ret;
} }
public Object visit(ASTIterationStatement node, Object data) { public Object visit(ASTIterationStatement node, Object data) {
@@ -306,12 +310,17 @@ public class CVisitor implements CParserVisitor {
public Object visit(ASTJumpStatement node, Object data) { public Object visit(ASTJumpStatement node, Object data) {
StringBuilder sb = new StringBuilder(""); StringBuilder sb = new StringBuilder("");
if (node.jjtGetNumChildren() > 0 && node.jjtGetChild(0) instanceof ASTExpression) { if (node.choice == 2) {
return "break";
} else if (node.choice == 3) {
return "continue";
} else if (node.choice == 4) {
((CContext) data).statement_end_sc = false; ((CContext) data).statement_end_sc = false;
sb.append(node.jjtGetChild(0).jjtAccept(this, data)); sb.append(node.jjtGetChild(0).jjtAccept(this, data));
} else { } else {
sb.append(defaultVisit(node, data)); sb.append(defaultVisit(node, data));
} }
return sb.toString(); return sb.toString();
} }
@@ -399,11 +408,13 @@ public class CVisitor implements CParserVisitor {
} }
public Object visit(ASTUnaryExpression node, Object data) { public Object visit(ASTUnaryExpression node, Object data) {
return defaultSpacedVisit(node, data, " ", false); String visit = (String) defaultVisit(node, data);
}
public Object visit(ASTUnaryOperator node, Object data) { if (node.choice > 1) {
return defaultVisit(node, data); return "(" + visit + ")";
} else {
return visit;
}
} }
public Object visit(ASTPostfixExpression node, Object data) { public Object visit(ASTPostfixExpression node, Object data) {
@@ -422,6 +433,12 @@ public class CVisitor implements CParserVisitor {
sb.append(node.jjtGetChild(1).jjtAccept(this, data)); sb.append(node.jjtGetChild(1).jjtAccept(this, data));
sb.append(")"); sb.append(")");
return sb.toString();
} else if (node.choice == 3) {
/* Field access */
sb.append(".");
sb.append(node.jjtGetChild(1).jjtAccept(this, data));
return sb.toString(); return sb.toString();
} }

View File

@@ -4,6 +4,8 @@ package ghidrust.decompiler.parser.c.gen;
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ /* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
public public
class ASTJumpStatement extends SimpleNode { class ASTJumpStatement extends SimpleNode {
public int choice;
public ASTJumpStatement(int id) { public ASTJumpStatement(int id) {
super(id); super(id);
} }

View File

@@ -4,6 +4,8 @@ package ghidrust.decompiler.parser.c.gen;
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ /* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
public public
class ASTUnaryExpression extends SimpleNode { class ASTUnaryExpression extends SimpleNode {
public int choice;
public ASTUnaryExpression(int id) { public ASTUnaryExpression(int id) {
super(id); super(id);
} }

View File

@@ -1,23 +0,0 @@
package ghidrust.decompiler.parser.c.gen;
/* Generated By:JJTree: Do not edit this line. ASTUnaryOperator.java Version 7.0 */
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
public
class ASTUnaryOperator extends SimpleNode {
public ASTUnaryOperator(int id) {
super(id);
}
public ASTUnaryOperator(CParser p, int id) {
super(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(CParserVisitor visitor, Object data) {
return
visitor.visit(this, data);
}
}
/* JavaCC - OriginalChecksum=6c43a4b6e42256ad16599f05ce4392a5 (do not edit this line) */

File diff suppressed because it is too large Load Diff

View File

@@ -150,9 +150,6 @@ public class CParserDefaultVisitor implements CParserVisitor{
public Object visit(ASTUnaryExpression node, Object data){ public Object visit(ASTUnaryExpression node, Object data){
return defaultVisit(node, data); return defaultVisit(node, data);
} }
public Object visit(ASTUnaryOperator node, Object data){
return defaultVisit(node, data);
}
public Object visit(ASTPostfixExpression node, Object data){ public Object visit(ASTPostfixExpression node, Object data){
return defaultVisit(node, data); return defaultVisit(node, data);
} }
@@ -163,4 +160,4 @@ public class CParserDefaultVisitor implements CParserVisitor{
return defaultVisit(node, data); return defaultVisit(node, data);
} }
} }
/* JavaCC - OriginalChecksum=02bd2f1bbfbe0abbaf156b1dcc67f14c (do not edit this line) */ /* JavaCC - OriginalChecksum=0df21b33819a468166075ef388879333 (do not edit this line) */

View File

@@ -50,10 +50,9 @@ public interface CParserTreeConstants
public int JJTMULTIPLICATIVEEXPRESSION = 44; public int JJTMULTIPLICATIVEEXPRESSION = 44;
public int JJTCASTEXPRESSION = 45; public int JJTCASTEXPRESSION = 45;
public int JJTUNARYEXPRESSION = 46; public int JJTUNARYEXPRESSION = 46;
public int JJTUNARYOPERATOR = 47; public int JJTPOSTFIXEXPRESSION = 47;
public int JJTPOSTFIXEXPRESSION = 48; public int JJTPRIMARYEXPRESSION = 48;
public int JJTPRIMARYEXPRESSION = 49; public int JJTARGUMENTEXPRESSIONLIST = 49;
public int JJTARGUMENTEXPRESSIONLIST = 50;
public String[] jjtNodeName = { public String[] jjtNodeName = {
@@ -104,10 +103,9 @@ public interface CParserTreeConstants
"MultiplicativeExpression", "MultiplicativeExpression",
"CastExpression", "CastExpression",
"UnaryExpression", "UnaryExpression",
"UnaryOperator",
"PostfixExpression", "PostfixExpression",
"PrimaryExpression", "PrimaryExpression",
"ArgumentExpressionList", "ArgumentExpressionList",
}; };
} }
/* JavaCC - OriginalChecksum=6fdc7fd778ad43f052fadf52075bfbaa (do not edit this line) */ /* JavaCC - OriginalChecksum=e23e00fb56ffad799524355d8342c899 (do not edit this line) */

View File

@@ -51,9 +51,8 @@ public interface CParserVisitor
public Object visit(ASTMultiplicativeExpression node, Object data); public Object visit(ASTMultiplicativeExpression node, Object data);
public Object visit(ASTCastExpression node, Object data); public Object visit(ASTCastExpression node, Object data);
public Object visit(ASTUnaryExpression node, Object data); public Object visit(ASTUnaryExpression node, Object data);
public Object visit(ASTUnaryOperator node, Object data);
public Object visit(ASTPostfixExpression node, Object data); public Object visit(ASTPostfixExpression node, Object data);
public Object visit(ASTPrimaryExpression node, Object data); public Object visit(ASTPrimaryExpression node, Object data);
public Object visit(ASTArgumentExpressionList node, Object data); public Object visit(ASTArgumentExpressionList node, Object data);
} }
/* JavaCC - OriginalChecksum=1f05897c3d57918f597035227f8d60dd (do not edit this line) */ /* JavaCC - OriginalChecksum=c11b3a8c5731c3cdcccff61a264d1174 (do not edit this line) */

View File

@@ -1110,18 +1110,29 @@ void IterationStatement() :
/*@egen*/ /*@egen*/
} }
void JumpStatement() : {/*@bgen(jjtree) JumpStatement */ void JumpStatement() :
ASTJumpStatement jjtn000 = new ASTJumpStatement(JJTJUMPSTATEMENT); {/*@bgen(jjtree) JumpStatement */
boolean jjtc000 = true; ASTJumpStatement jjtn000 = new ASTJumpStatement(JJTJUMPSTATEMENT);
jjtree.openNodeScope(jjtn000); boolean jjtc000 = true;
/*@egen*/} jjtree.openNodeScope(jjtn000);
/*@egen*/
int choice = 0;
}
{/*@bgen(jjtree) JumpStatement */ {/*@bgen(jjtree) JumpStatement */
try { try {
/*@egen*/ /*@egen*/
( <GOTO> Identifier() ";" | ( <GOTO> Identifier() ";" | { choice = 1; }
<CONTINUE> ";" | <CONTINUE> ";" | { choice = 2; }
<BREAK> ";" | <BREAK> ";" | { choice = 3; }
<RETURN> [ Expression() ] ";" )/*@bgen(jjtree)*/ <RETURN> [ Expression() ] ";" { choice = 4; } )/*@bgen(jjtree)*/
{
jjtree.closeNodeScope(jjtn000, true);
jjtc000 = false;
}
/*@egen*/
{
jjtn000.choice = choice;
}/*@bgen(jjtree)*/
} catch (Throwable jjte000) { } catch (Throwable jjte000) {
if (jjtc000) { if (jjtc000) {
jjtree.clearNodeScope(jjtn000); jjtree.clearNodeScope(jjtn000);
@@ -1460,7 +1471,7 @@ void EqualityExpression() : {/*@bgen(jjtree) EqualityExpression */
{/*@bgen(jjtree) EqualityExpression */ {/*@bgen(jjtree) EqualityExpression */
try { try {
/*@egen*/ /*@egen*/
RelationalExpression() [ ( "==" | "!=" ) EqualityExpression() ]/*@bgen(jjtree)*/ RelationalExpression() [ EqualityOperator() EqualityExpression() ]/*@bgen(jjtree)*/
} catch (Throwable jjte000) { } catch (Throwable jjte000) {
if (jjtc000) { if (jjtc000) {
jjtree.clearNodeScope(jjtn000); jjtree.clearNodeScope(jjtn000);
@@ -1483,6 +1494,34 @@ void EqualityExpression() : {/*@bgen(jjtree) EqualityExpression */
/*@egen*/ /*@egen*/
} }
void EqualityOperator() :
{/*@bgen(jjtree) StringToken */
ASTStringToken jjtn000 = new ASTStringToken(JJTSTRINGTOKEN);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
/*@egen*/
Token t;
}
{/*@bgen(jjtree) StringToken */
try {
/*@egen*/
( t = "==" | t = "!=" )/*@bgen(jjtree)*/
{
jjtree.closeNodeScope(jjtn000, true);
jjtc000 = false;
}
/*@egen*/
{
jjtn000.image = t.image;
}/*@bgen(jjtree)*/
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
}
}
/*@egen*/
}
void RelationalExpression() : {/*@bgen(jjtree) RelationalExpression */ void RelationalExpression() : {/*@bgen(jjtree) RelationalExpression */
ASTRelationalExpression jjtn000 = new ASTRelationalExpression(JJTRELATIONALEXPRESSION); ASTRelationalExpression jjtn000 = new ASTRelationalExpression(JJTRELATIONALEXPRESSION);
boolean jjtc000 = true; boolean jjtc000 = true;
@@ -1491,7 +1530,7 @@ void RelationalExpression() : {/*@bgen(jjtree) RelationalExpression */
{/*@bgen(jjtree) RelationalExpression */ {/*@bgen(jjtree) RelationalExpression */
try { try {
/*@egen*/ /*@egen*/
ShiftExpression() [( "<" | ">" | "<=" | ">=" ) RelationalExpression()]/*@bgen(jjtree)*/ ShiftExpression() [ComparaisonOperator() RelationalExpression()]/*@bgen(jjtree)*/
} catch (Throwable jjte000) { } catch (Throwable jjte000) {
if (jjtc000) { if (jjtc000) {
jjtree.clearNodeScope(jjtn000); jjtree.clearNodeScope(jjtn000);
@@ -1514,6 +1553,34 @@ void RelationalExpression() : {/*@bgen(jjtree) RelationalExpression */
/*@egen*/ /*@egen*/
} }
void ComparaisonOperator() :
{/*@bgen(jjtree) StringToken */
ASTStringToken jjtn000 = new ASTStringToken(JJTSTRINGTOKEN);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
/*@egen*/
Token t;
}
{/*@bgen(jjtree) StringToken */
try {
/*@egen*/
( t = "<" | t = ">" | t = "<=" | t = ">=" )/*@bgen(jjtree)*/
{
jjtree.closeNodeScope(jjtn000, true);
jjtc000 = false;
}
/*@egen*/
{
jjtn000.image = t.image;
}/*@bgen(jjtree)*/
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
}
}
/*@egen*/
}
void ShiftExpression() : {/*@bgen(jjtree) ShiftExpression */ void ShiftExpression() : {/*@bgen(jjtree) ShiftExpression */
ASTShiftExpression jjtn000 = new ASTShiftExpression(JJTSHIFTEXPRESSION); ASTShiftExpression jjtn000 = new ASTShiftExpression(JJTSHIFTEXPRESSION);
boolean jjtc000 = true; boolean jjtc000 = true;
@@ -1667,19 +1734,30 @@ void CastExpression() : {/*@bgen(jjtree) CastExpression */
/*@egen*/ /*@egen*/
} }
void UnaryExpression() : {/*@bgen(jjtree) UnaryExpression */ void UnaryExpression() :
ASTUnaryExpression jjtn000 = new ASTUnaryExpression(JJTUNARYEXPRESSION); {/*@bgen(jjtree) UnaryExpression */
boolean jjtc000 = true; ASTUnaryExpression jjtn000 = new ASTUnaryExpression(JJTUNARYEXPRESSION);
jjtree.openNodeScope(jjtn000); boolean jjtc000 = true;
/*@egen*/} jjtree.openNodeScope(jjtn000);
/*@egen*/
int choice = 0;
}
{/*@bgen(jjtree) UnaryExpression */ {/*@bgen(jjtree) UnaryExpression */
try { try {
/*@egen*/ /*@egen*/
( LOOKAHEAD(3) PostfixExpression() | ( LOOKAHEAD(3) PostfixExpression() { choice = 1; } |
"++" UnaryExpression() | "++" UnaryExpression() { choice = 2; } |
"--" UnaryExpression() | "--" UnaryExpression() { choice = 3; } |
UnaryOperator() CastExpression() | UnaryOperator() CastExpression() { choice = 4; } |
<SIZEOF> ( LOOKAHEAD(UnaryExpression() ) UnaryExpression() | "(" TypeName() ")" ) )/*@bgen(jjtree)*/ <SIZEOF> ( LOOKAHEAD(UnaryExpression() ) UnaryExpression() { choice = 5; } | "(" TypeName() ")" ) { choice = 6; } )/*@bgen(jjtree)*/
{
jjtree.closeNodeScope(jjtn000, true);
jjtc000 = false;
}
/*@egen*/
{
jjtn000.choice = choice;
}/*@bgen(jjtree)*/
} catch (Throwable jjte000) { } catch (Throwable jjte000) {
if (jjtc000) { if (jjtc000) {
jjtree.clearNodeScope(jjtn000); jjtree.clearNodeScope(jjtn000);
@@ -1702,15 +1780,26 @@ void UnaryExpression() : {/*@bgen(jjtree) UnaryExpression */
/*@egen*/ /*@egen*/
} }
void UnaryOperator() : {/*@bgen(jjtree) UnaryOperator */ void UnaryOperator() :
ASTUnaryOperator jjtn000 = new ASTUnaryOperator(JJTUNARYOPERATOR); {/*@bgen(jjtree) StringToken */
boolean jjtc000 = true; ASTStringToken jjtn000 = new ASTStringToken(JJTSTRINGTOKEN);
jjtree.openNodeScope(jjtn000); boolean jjtc000 = true;
/*@egen*/} jjtree.openNodeScope(jjtn000);
{/*@bgen(jjtree) UnaryOperator */ /*@egen*/
Token t;
}
{/*@bgen(jjtree) StringToken */
try { try {
/*@egen*/ /*@egen*/
( "&" | "*" | "+" | "-" | "~" | "!" )/*@bgen(jjtree)*/ ( t = "&" | t = "*" | t = "+" | t = "-" | t = "~" | t = "!" )/*@bgen(jjtree)*/
{
jjtree.closeNodeScope(jjtn000, true);
jjtc000 = false;
}
/*@egen*/
{
jjtn000.image = t.image;
}/*@bgen(jjtree)*/
} finally { } finally {
if (jjtc000) { if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true); jjtree.closeNodeScope(jjtn000, true);

View File

@@ -343,12 +343,18 @@ void IterationStatement() :
} }
} }
void JumpStatement() : {} void JumpStatement() :
{ {
( <GOTO> Identifier() ";" | int choice = 0;
<CONTINUE> ";" | }
<BREAK> ";" | {
<RETURN> [ Expression() ] ";" ) ( <GOTO> Identifier() ";" | { choice = 1; }
<CONTINUE> ";" | { choice = 2; }
<BREAK> ";" | { choice = 3; }
<RETURN> [ Expression() ] ";" { choice = 4; } )
{
jjtThis.choice = choice;
}
} }
void Expression() : {} void Expression() : {}
@@ -410,12 +416,34 @@ void ANDExpression() : {}
void EqualityExpression() : {} void EqualityExpression() : {}
{ {
RelationalExpression() [ ( "==" | "!=" ) EqualityExpression() ] RelationalExpression() [ EqualityOperator() EqualityExpression() ]
}
void EqualityOperator() #StringToken :
{
Token t;
}
{
( t = "==" | t = "!=" )
{
jjtThis.image = t.image;
}
} }
void RelationalExpression() : {} void RelationalExpression() : {}
{ {
ShiftExpression() [( "<" | ">" | "<=" | ">=" ) RelationalExpression()] ShiftExpression() [ComparaisonOperator() RelationalExpression()]
}
void ComparaisonOperator() #StringToken :
{
Token t;
}
{
( t = "<" | t = ">" | t = "<=" | t = ">=" )
{
jjtThis.image = t.image;
}
} }
void ShiftExpression() : {} void ShiftExpression() : {}
@@ -450,18 +478,30 @@ void CastExpression() : {}
UnaryExpression() ) UnaryExpression() )
} }
void UnaryExpression() : {} void UnaryExpression() :
{ {
( LOOKAHEAD(3) PostfixExpression() | int choice = 0;
"++" UnaryExpression() | }
"--" UnaryExpression() | {
UnaryOperator() CastExpression() | ( LOOKAHEAD(3) PostfixExpression() { choice = 1; } |
<SIZEOF> ( LOOKAHEAD(UnaryExpression() ) UnaryExpression() | "(" TypeName() ")" ) ) "++" UnaryExpression() { choice = 2; } |
"--" UnaryExpression() { choice = 3; } |
UnaryOperator() CastExpression() { choice = 4; } |
<SIZEOF> ( LOOKAHEAD(UnaryExpression() ) UnaryExpression() { choice = 5; } | "(" TypeName() ")" ) { choice = 6; } )
{
jjtThis.choice = choice;
}
} }
void UnaryOperator() : {} void UnaryOperator() #StringToken :
{ {
( "&" | "*" | "+" | "-" | "~" | "!" ) Token t;
}
{
( t = "&" | t = "*" | t = "+" | t = "-" | t = "~" | t = "!" )
{
jjtThis.image = t.image;
}
} }
void PostfixExpression() : { void PostfixExpression() : {

View File

@@ -4,7 +4,7 @@
cd c/gen cd c/gen
BACKUP_FILES="ASTPostfixExpression ASTIterationStatement \ BACKUP_FILES="ASTPostfixExpression ASTIterationStatement ASTUnaryExpression ASTJumpStatement \
$(ls -1 AST*Token.java | cut -d. -f1 | tr '\n' ' ')" $(ls -1 AST*Token.java | cut -d. -f1 | tr '\n' ' ')"
for file in $BACKUP_FILES; do for file in $BACKUP_FILES; do