test_custom_latex.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import os
  2. import tempfile
  3. from pathlib import Path
  4. import sympy
  5. from sympy.testing.pytest import raises
  6. from sympy.parsing.latex.lark import LarkLaTeXParser, TransformToSymPyExpr, parse_latex_lark
  7. from sympy.external import import_module
  8. lark = import_module("lark")
  9. # disable tests if lark is not present
  10. disabled = lark is None
  11. grammar_file = os.path.join(os.path.dirname(__file__), "../latex/lark/grammar/latex.lark")
  12. modification1 = """
  13. %override DIV_SYMBOL: DIV
  14. %override MUL_SYMBOL: MUL | CMD_TIMES
  15. """
  16. modification2 = r"""
  17. %override number: /\d+(,\d*)?/
  18. """
  19. def init_custom_parser(modification, transformer=None):
  20. latex_grammar = Path(grammar_file).read_text(encoding="utf-8")
  21. latex_grammar += modification
  22. with tempfile.NamedTemporaryFile() as f:
  23. f.write(bytes(latex_grammar, encoding="utf8"))
  24. f.flush()
  25. parser = LarkLaTeXParser(grammar_file=f.name, transformer=transformer)
  26. return parser
  27. def test_custom1():
  28. # Removes the parser's ability to understand \cdot and \div.
  29. parser = init_custom_parser(modification1)
  30. with raises(lark.exceptions.UnexpectedCharacters):
  31. parser.doparse(r"a \cdot b")
  32. parser.doparse(r"x \div y")
  33. class CustomTransformer(TransformToSymPyExpr):
  34. def number(self, tokens):
  35. if "," in tokens[0]:
  36. # The Float constructor expects a dot as the decimal separator
  37. return sympy.core.numbers.Float(tokens[0].replace(",", "."))
  38. else:
  39. return sympy.core.numbers.Integer(tokens[0])
  40. def test_custom2():
  41. # Makes the parser parse commas as the decimal separator instead of dots
  42. parser = init_custom_parser(modification2, CustomTransformer)
  43. with raises(lark.exceptions.UnexpectedCharacters):
  44. # Asserting that the default parser cannot parse numbers which have commas as
  45. # the decimal separator
  46. parse_latex_lark("100,1")
  47. parse_latex_lark("0,009")
  48. parser.doparse("100,1")
  49. parser.doparse("0,009")
  50. parser.doparse("2,71828")
  51. parser.doparse("3,14159")