GeezerVison is showing github.com — String formatting as AST transform (1st iteration) · akumar5/java2python@6a8ded2
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: java2python/config/default.py +6-1Lines changed: 6 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 162 | 162 | (Type('METHOD_CALL') > Type('DOT') > Type('IDENT', 'length'), | 163 | 163 | transform.lengthToLen), | 164 | 164 |
| | 165 | + (Type('METHOD_CALL') > Type('DOT') > ( | | 166 | + Type('IDENT', 'String') + | | 167 | + Type('IDENT', 'format') | | 168 | + ), | | 169 | + transform.formatString), | | 170 | + | 165 | 171 | (Type('TYPE') > Type('QUALIFIED_TYPE_IDENT') > Type('IDENT'), | 166 | 172 | transform.typeSub), | 167 | 173 |
| | 189 | 195 | moduleOutputSubs = [ | 190 | 196 | (r'System\.out\.println\((.*)\)', r'print \1'), | 191 | 197 | (r'System\.out\.print_\((.*?)\)', r'print \1,'), | 192 | | - (r'String\.format\(\"(.*)\" *, *(.*)\)', r'"\1" % (\2)'), | 193 | 198 | (r'(.*?)\.equals\((.*?)\)', r'\1 == \2'), | 194 | 199 | (r'(.*?)\.equalsIgnoreCase\((.*?)\)', r'\1.lower() == \2.lower()'), | 195 | 200 | (r'([\w.]+)\.size\(\)', r'len(\1)'), | |
Collapse file Copy file name to clipboardExpand all lines: java2python/mod/transform.py +49Lines changed: 49 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 11 | 11 | # See the java2python.config.default and java2python.lang.selector modules to | 12 | 12 | # understand how and when selectors are associated with these callables. | 13 | 13 |
| | 14 | +import re | | 15 | + | 14 | 16 | import keyword | 15 | 17 | import types | 16 | 18 |
| @@ -89,6 +91,53 @@ def lengthToLen(node, config): | 89 | 91 | expr.addChild(ident) | 90 | 92 |
| 91 | 93 |
| | 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 | + | 92 | 141 | def typeSub(node, config): | 93 | 142 | """ Maps specific, well-known Java types to their Python counterparts. | 94 | 143 |
| |
Collapse file Copy file name to clipboardExpand all lines: test/Format0.java +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 1 | | -public class Format { | | 1 | +public class Format0 { | 2 | 2 | public static void main(String[] args) { | 3 | 3 | int i = 22; | 4 | 4 | String s = "text"; | 5 | | - String r = String.format("> (%d) %s", i, s); | | 5 | + String r = String.format("> (%1$d) %2$s", i, s); | 6 | 6 |
| 7 | 7 | System.out.println(r); | 8 | 8 | } | |
|