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,12 +277,16 @@ public class CVisitor implements CParserVisitor {
}
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) {
StringBuilder sb = new StringBuilder("");
if (node.choice == 1) {
((CContext) data).statement_end_sc = false;
@@ -294,24 +298,29 @@ public class CVisitor implements CParserVisitor {
sb.append("}");
} else if (node.choice == 2) {
sb.append("do {");
sb.append(node.jjtGetChild(0).jjtAccept(this, data));
sb.append(node.jjtGetChild(0).jjtAccept(this, data));
sb.append("} while (");
sb.append(node.jjtGetChild(1).jjtAccept(this, data));
sb.append(")");
}
return sb.toString();
}
public Object visit(ASTJumpStatement node, Object data) {
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;
sb.append(node.jjtGetChild(0).jjtAccept(this, data));
} else {
sb.append(defaultVisit(node, data));
}
return sb.toString();
}
@@ -399,11 +408,13 @@ public class CVisitor implements CParserVisitor {
}
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) {
return defaultVisit(node, data);
if (node.choice > 1) {
return "(" + visit + ")";
} else {
return visit;
}
}
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(")");
return sb.toString();
} else if (node.choice == 3) {
/* Field access */
sb.append(".");
sb.append(node.jjtGetChild(1).jjtAccept(this, data));
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 */
public
class ASTJumpStatement extends SimpleNode {
public int choice;
public ASTJumpStatement(int 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 */
public
class ASTUnaryExpression extends SimpleNode {
public int choice;
public ASTUnaryExpression(int 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){
return defaultVisit(node, data);
}
public Object visit(ASTUnaryOperator node, Object data){
return defaultVisit(node, data);
}
public Object visit(ASTPostfixExpression node, Object data){
return defaultVisit(node, data);
}
@@ -163,4 +160,4 @@ public class CParserDefaultVisitor implements CParserVisitor{
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 JJTCASTEXPRESSION = 45;
public int JJTUNARYEXPRESSION = 46;
public int JJTUNARYOPERATOR = 47;
public int JJTPOSTFIXEXPRESSION = 48;
public int JJTPRIMARYEXPRESSION = 49;
public int JJTARGUMENTEXPRESSIONLIST = 50;
public int JJTPOSTFIXEXPRESSION = 47;
public int JJTPRIMARYEXPRESSION = 48;
public int JJTARGUMENTEXPRESSIONLIST = 49;
public String[] jjtNodeName = {
@@ -104,10 +103,9 @@ public interface CParserTreeConstants
"MultiplicativeExpression",
"CastExpression",
"UnaryExpression",
"UnaryOperator",
"PostfixExpression",
"PrimaryExpression",
"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(ASTCastExpression 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(ASTPrimaryExpression 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*/
}
void JumpStatement() : {/*@bgen(jjtree) JumpStatement */
ASTJumpStatement jjtn000 = new ASTJumpStatement(JJTJUMPSTATEMENT);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
/*@egen*/}
void JumpStatement() :
{/*@bgen(jjtree) JumpStatement */
ASTJumpStatement jjtn000 = new ASTJumpStatement(JJTJUMPSTATEMENT);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
/*@egen*/
int choice = 0;
}
{/*@bgen(jjtree) JumpStatement */
try {
/*@egen*/
( <GOTO> Identifier() ";" |
<CONTINUE> ";" |
<BREAK> ";" |
<RETURN> [ Expression() ] ";" )/*@bgen(jjtree)*/
( <GOTO> Identifier() ";" | { choice = 1; }
<CONTINUE> ";" | { choice = 2; }
<BREAK> ";" | { choice = 3; }
<RETURN> [ Expression() ] ";" { choice = 4; } )/*@bgen(jjtree)*/
{
jjtree.closeNodeScope(jjtn000, true);
jjtc000 = false;
}
/*@egen*/
{
jjtn000.choice = choice;
}/*@bgen(jjtree)*/
} catch (Throwable jjte000) {
if (jjtc000) {
jjtree.clearNodeScope(jjtn000);
@@ -1460,7 +1471,7 @@ void EqualityExpression() : {/*@bgen(jjtree) EqualityExpression */
{/*@bgen(jjtree) EqualityExpression */
try {
/*@egen*/
RelationalExpression() [ ( "==" | "!=" ) EqualityExpression() ]/*@bgen(jjtree)*/
RelationalExpression() [ EqualityOperator() EqualityExpression() ]/*@bgen(jjtree)*/
} catch (Throwable jjte000) {
if (jjtc000) {
jjtree.clearNodeScope(jjtn000);
@@ -1483,6 +1494,34 @@ void EqualityExpression() : {/*@bgen(jjtree) EqualityExpression */
/*@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 */
ASTRelationalExpression jjtn000 = new ASTRelationalExpression(JJTRELATIONALEXPRESSION);
boolean jjtc000 = true;
@@ -1491,7 +1530,7 @@ void RelationalExpression() : {/*@bgen(jjtree) RelationalExpression */
{/*@bgen(jjtree) RelationalExpression */
try {
/*@egen*/
ShiftExpression() [( "<" | ">" | "<=" | ">=" ) RelationalExpression()]/*@bgen(jjtree)*/
ShiftExpression() [ComparaisonOperator() RelationalExpression()]/*@bgen(jjtree)*/
} catch (Throwable jjte000) {
if (jjtc000) {
jjtree.clearNodeScope(jjtn000);
@@ -1514,6 +1553,34 @@ void RelationalExpression() : {/*@bgen(jjtree) RelationalExpression */
/*@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 */
ASTShiftExpression jjtn000 = new ASTShiftExpression(JJTSHIFTEXPRESSION);
boolean jjtc000 = true;
@@ -1667,19 +1734,30 @@ void CastExpression() : {/*@bgen(jjtree) CastExpression */
/*@egen*/
}
void UnaryExpression() : {/*@bgen(jjtree) UnaryExpression */
ASTUnaryExpression jjtn000 = new ASTUnaryExpression(JJTUNARYEXPRESSION);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
/*@egen*/}
void UnaryExpression() :
{/*@bgen(jjtree) UnaryExpression */
ASTUnaryExpression jjtn000 = new ASTUnaryExpression(JJTUNARYEXPRESSION);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
/*@egen*/
int choice = 0;
}
{/*@bgen(jjtree) UnaryExpression */
try {
/*@egen*/
( LOOKAHEAD(3) PostfixExpression() |
"++" UnaryExpression() |
"--" UnaryExpression() |
UnaryOperator() CastExpression() |
<SIZEOF> ( LOOKAHEAD(UnaryExpression() ) UnaryExpression() | "(" TypeName() ")" ) )/*@bgen(jjtree)*/
( LOOKAHEAD(3) PostfixExpression() { choice = 1; } |
"++" UnaryExpression() { choice = 2; } |
"--" UnaryExpression() { choice = 3; } |
UnaryOperator() CastExpression() { choice = 4; } |
<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) {
if (jjtc000) {
jjtree.clearNodeScope(jjtn000);
@@ -1702,15 +1780,26 @@ void UnaryExpression() : {/*@bgen(jjtree) UnaryExpression */
/*@egen*/
}
void UnaryOperator() : {/*@bgen(jjtree) UnaryOperator */
ASTUnaryOperator jjtn000 = new ASTUnaryOperator(JJTUNARYOPERATOR);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) UnaryOperator */
void UnaryOperator() :
{/*@bgen(jjtree) StringToken */
ASTStringToken jjtn000 = new ASTStringToken(JJTSTRINGTOKEN);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
/*@egen*/
Token t;
}
{/*@bgen(jjtree) StringToken */
try {
/*@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 {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);

View File

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

View File

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