_build_autolev_antlr.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import os
  2. import subprocess
  3. import glob
  4. from sympy.utilities.misc import debug
  5. here = os.path.dirname(__file__)
  6. grammar_file = os.path.abspath(os.path.join(here, "Autolev.g4"))
  7. dir_autolev_antlr = os.path.join(here, "_antlr")
  8. header = '''\
  9. # *** GENERATED BY `setup.py antlr`, DO NOT EDIT BY HAND ***
  10. #
  11. # Generated with antlr4
  12. # antlr4 is licensed under the BSD-3-Clause License
  13. # https://github.com/antlr/antlr4/blob/master/LICENSE.txt
  14. '''
  15. def check_antlr_version():
  16. debug("Checking antlr4 version...")
  17. try:
  18. debug(subprocess.check_output(["antlr4"])
  19. .decode('utf-8').split("\n")[0])
  20. return True
  21. except (subprocess.CalledProcessError, FileNotFoundError):
  22. debug("The 'antlr4' command line tool is not installed, "
  23. "or not on your PATH.\n"
  24. "> Please refer to the README.md file for more information.")
  25. return False
  26. def build_parser(output_dir=dir_autolev_antlr):
  27. check_antlr_version()
  28. debug("Updating ANTLR-generated code in {}".format(output_dir))
  29. if not os.path.exists(output_dir):
  30. os.makedirs(output_dir)
  31. with open(os.path.join(output_dir, "__init__.py"), "w+") as fp:
  32. fp.write(header)
  33. args = [
  34. "antlr4",
  35. grammar_file,
  36. "-o", output_dir,
  37. "-no-visitor",
  38. ]
  39. debug("Running code generation...\n\t$ {}".format(" ".join(args)))
  40. subprocess.check_output(args, cwd=output_dir)
  41. debug("Applying headers, removing unnecessary files and renaming...")
  42. # Handle case insensitive file systems. If the files are already
  43. # generated, they will be written to autolev* but Autolev*.* won't match them.
  44. for path in (glob.glob(os.path.join(output_dir, "Autolev*.*")) or
  45. glob.glob(os.path.join(output_dir, "autolev*.*"))):
  46. # Remove files ending in .interp or .tokens as they are not needed.
  47. if not path.endswith(".py"):
  48. os.unlink(path)
  49. continue
  50. new_path = os.path.join(output_dir, os.path.basename(path).lower())
  51. with open(path, 'r') as f:
  52. lines = [line.rstrip().replace('AutolevParser import', 'autolevparser import') +'\n'
  53. for line in f.readlines()]
  54. os.unlink(path)
  55. with open(new_path, "w") as out_file:
  56. offset = 0
  57. while lines[offset].startswith('#'):
  58. offset += 1
  59. out_file.write(header)
  60. out_file.writelines(lines[offset:])
  61. debug("\t{}".format(new_path))
  62. return True
  63. if __name__ == "__main__":
  64. build_parser()