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

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 

11 

12 

13def r2python(code: str, pep8=False, fLOG=None) -> str: 

14 """ 

15 Converts a R script into Python. 

16 

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 

21 

22 .. _code-r2python: 

23 

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/>`_. 

27 

28 .. exref:: 

29 :title: Convert R into Python 

30 

31 .. runpython:: 

32 :showcode: 

33 

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 ''' 

43 

44 from pyensae.languages.rconverter import r2python 

45 print(r2python(rscript, pep8=True)) 

46 

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. 

53 

54 Kwonws bugs: 

55 

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 

61 

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