Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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 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 if fLOG: 

63 fLOG( # pragma: no cover 

64 "[r2python] parse ", len(code), "bytes") 

65 parser = parse_code(code, RParser, RLexer) 

66 if fLOG: 

67 fLOG( # pragma: no cover 

68 "[r2python] parse continue") 

69 parsed = parser.parse() 

70 if fLOG: 

71 fLOG( # pragma: no cover 

72 "[r2python] listen") 

73 listen = TreeStringListener(parsed, fLOG=fLOG) 

74 walker = ParseTreeWalker() 

75 if fLOG: 

76 fLOG( # pragma: no cover 

77 "[r2python] walk") 

78 walker.walk(listen, parsed) 

79 if fLOG: 

80 fLOG( # pragma: no cover 

81 "[r2python] get code") 

82 code = listen.get_python() 

83 if pep8: 

84 if fLOG: 

85 fLOG( # pragma: no cover 

86 "[r2python] pep8") 

87 code = remove_extra_spaces_and_pep8(code, aggressive=True) 

88 return code