Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6a8ded2

Browse files
committed
String formatting as AST transform (1st iteration)
1 parent a839a71 commit 6a8ded2

File tree

3 files changed

+57
-3
lines changed

3 files changed

+57
-3
lines changed

java2python/config/default.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,12 @@
162162
(Type('METHOD_CALL') > Type('DOT') > Type('IDENT', 'length'),
163163
transform.lengthToLen),
164164

165+
(Type('METHOD_CALL') > Type('DOT') > (
166+
Type('IDENT', 'String') +
167+
Type('IDENT', 'format')
168+
),
169+
transform.formatString),
170+
165171
(Type('TYPE') > Type('QUALIFIED_TYPE_IDENT') > Type('IDENT'),
166172
transform.typeSub),
167173

@@ -189,7 +195,6 @@
189195
moduleOutputSubs = [
190196
(r'System\.out\.println\((.*)\)', r'print \1'),
191197
(r'System\.out\.print_\((.*?)\)', r'print \1,'),
192-
(r'String\.format\(\"(.*)\" *, *(.*)\)', r'"\1" % (\2)'),
193198
(r'(.*?)\.equals\((.*?)\)', r'\1 == \2'),
194199
(r'(.*?)\.equalsIgnoreCase\((.*?)\)', r'\1.lower() == \2.lower()'),
195200
(r'([\w.]+)\.size\(\)', r'len(\1)'),

java2python/mod/transform.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
# See the java2python.config.default and java2python.lang.selector modules to
1212
# understand how and when selectors are associated with these callables.
1313

14+
import re
15+
1416
import keyword
1517
import types
1618

@@ -89,6 +91,53 @@ def lengthToLen(node, config):
8991
expr.addChild(ident)
9092

9193

94+
def formatSyntaxTransf(match):
95+
""" Helper function for formatString AST transform.
96+
97+
Translates the Java Formatter syntax into Python .format syntax.
98+
99+
This function gets called by re.sub which matches all the %...$... groups
100+
inside a format specifier string.
101+
"""
102+
groups = match.groupdict()
103+
result = '{'
104+
# TODO: add flags, width and precision
105+
if(groups['idx']):
106+
idx = int(groups['idx'][:-1])
107+
result += str(idx - 1) # Py starts count from 0
108+
result += ':' + groups['convers'] + '}'
109+
110+
return result
111+
112+
def formatString(node, config):
113+
""" Transforms string formatting like 'String.format("%d %2$s", i, s)'
114+
into '"{:d} {2:s}".format(i, s)'.
115+
"""
116+
dot = node.parent
117+
method = dot.parent
118+
arg_list = method.firstChildOfType(tokens.ARGUMENT_LIST)
119+
call_args = [arg for arg in arg_list.childrenOfType(tokens.EXPR)]
120+
121+
format = call_args[0].firstChildOfType(tokens.STRING_LITERAL)
122+
args = [arg.firstChildOfType(tokens.IDENT) for arg in call_args[1:]]
123+
124+
# Translate format syntax
125+
format.token.text = re.sub(r'%(?P<idx>\d+\$)?(?P<convers>[scdoxefg])',
126+
formatSyntaxTransf,
127+
format.token.text,
128+
flags=re.IGNORECASE)
129+
130+
left_ident = dot.children[0]
131+
right_ident = dot.children[1]
132+
133+
# Change AST
134+
arg_list.children.remove(format.parent)
135+
dot.children.remove(left_ident)
136+
dot.children.remove(right_ident)
137+
dot.addChild(format)
138+
dot.addChild(right_ident)
139+
140+
92141
def typeSub(node, config):
93142
""" Maps specific, well-known Java types to their Python counterparts.
94143

test/Format0.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
public class Format {
1+
public class Format0 {
22
public static void main(String[] args) {
33
int i = 22;
44
String s = "text";
5-
String r = String.format("> (%d) %s", i, s);
5+
String r = String.format("> (%1$d) %2$s", i, s);
66

77
System.out.println(r);
88
}

0 commit comments

Comments
 (0)