Coverage for src/pyensae/languages/rconverter.py: 0%
22 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-03 02:16 +0200
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-03 02:16 +0200
1"""
2@file
3@brief Convert R into Python
4"""
5from antlr4 import ParseTreeWalker
6from pyquickhelper.pycode import remove_extra_spaces_and_pep8
7from .RParser import RParser
8from .RLexer import RLexer
9from .antlr_grammar_use import parse_code
10from .rconverterListener import TreeStringListener
13def r2python(code: str, pep8=False, fLOG=None) -> str:
14 """
15 Converts a R script into Python.
17 :param code: R string
18 :param pep8: modify the output to be compliant with pep8
19 :param fLOG: logging function
20 :return: Python string
22 .. _code-r2python:
24 The function uses a customized R grammar implemented with Antlr4.
25 Formula becomes strings. They should be handled with
26 `patsy <http://patsy.readthedocs.io/en/latest/>`_.
28 .. exref::
29 :title: Convert R into Python
31 .. runpython::
32 :showcode:
34 rscript = '''
35 nb=function(y=1930){
36 debut=1816
37 MatDFemale=matrix(D$Female,nrow=111)
38 colnames(MatDFemale)=(debut+0):198
39 cly=(y-debut+1):111
40 deces=diag(MatDFemale[:,cly[cly%in%1:199]])
41 return(c(B$Female[B$Year==y],deces))}
42 '''
44 from pyensae.languages.rconverter import r2python
45 print(r2python(rscript, pep8=True))
47 Some patterns are not well migrated such expression ``a:b`` into ``range(a,b)``.
48 The grammar could be improved to detect the beginning of the expression but
49 for now, if the function fails to do the conversion, ``a:b`` must be written
50 into ``(a):b``. The same trick is sometimes needed for other patterns
51 such as the operator ``%in%`` which is converted into an intersection
52 of two sets.
54 Kwonws bugs:
56 * ``} else {`` needs to be replaced by ``} EOL else {``
57 * comment added at the end of line must be followed by an empty line
58 * ``m[,1]`` must be replaced by ``M[:,1]``
59 * formula ``~.`` is not translated
60 * ``%<%`` cannot be followed by an empty line
62 The grammar were updated in 2022 for python 3.10 and
63 :epkg:`antlr4-python3-runtime` == 4.10.
64 """
65 if fLOG:
66 fLOG( # pragma: no cover
67 "[r2python] parse ", len(code), "bytes")
68 parser = parse_code(code, RParser, RLexer)
69 if fLOG:
70 fLOG( # pragma: no cover
71 "[r2python] parse continue")
72 parsed = parser.parse()
73 if fLOG:
74 fLOG( # pragma: no cover
75 "[r2python] listen")
76 listen = TreeStringListener(parsed, fLOG=fLOG)
77 walker = ParseTreeWalker()
78 if fLOG:
79 fLOG( # pragma: no cover
80 "[r2python] walk")
81 walker.walk(listen, parsed)
82 if fLOG:
83 fLOG( # pragma: no cover
84 "[r2python] get code")
85 code = listen.get_python()
86 if pep8:
87 if fLOG:
88 fLOG( # pragma: no cover
89 "[r2python] pep8")
90 code = remove_extra_spaces_and_pep8(code, aggressive=True)
91 return code