This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

106 lines
1.7 KiB

  1. """
  2. This example demonstrates how to transform a parse-tree into an AST using `lark.ast_utils`.
  3. This example only works with Python 3.
  4. """
  5. import sys
  6. from typing import List
  7. from dataclasses import dataclass
  8. from lark import Lark, ast_utils, Transformer, v_args
  9. this_module = sys.modules[__name__]
  10. #
  11. # Define AST
  12. #
  13. class _Ast(ast_utils.Ast):
  14. pass
  15. class _Statement(_Ast):
  16. pass
  17. @dataclass
  18. class Value(_Ast):
  19. value: object
  20. @dataclass
  21. class Name(_Ast):
  22. name: str
  23. @dataclass
  24. class CodeBlock(_Ast, ast_utils.AsList):
  25. statements: List[_Statement]
  26. @dataclass
  27. class If(_Statement):
  28. cond: Value
  29. then: CodeBlock
  30. @dataclass
  31. class SetVar(_Statement):
  32. name: str
  33. value: Value
  34. @dataclass
  35. class Print(_Statement):
  36. value: Value
  37. class ToAst(Transformer):
  38. def STRING(self, s):
  39. # Remove quotation marks
  40. return s[1:-1]
  41. def DEC_NUMBER(self, n):
  42. return int(n)
  43. @v_args(inline=True)
  44. def start(self, x):
  45. return x
  46. #
  47. # Define Parser
  48. #
  49. parser = Lark("""
  50. start: code_block
  51. code_block: statement+
  52. ?statement: if | set_var | print
  53. if: "if" value "{" code_block "}"
  54. set_var: NAME "=" value ";"
  55. print: "print" value ";"
  56. value: name | STRING | DEC_NUMBER
  57. name: NAME
  58. %import python (NAME, STRING, DEC_NUMBER)
  59. %import common.WS
  60. %ignore WS
  61. """,
  62. parser="lalr",
  63. )
  64. transformer = ast_utils.create_transformer(this_module, ToAst())
  65. def parse(text):
  66. return transformer.transform(parser.parse(text))
  67. #
  68. # Test
  69. #
  70. if __name__ == '__main__':
  71. print(parse("""
  72. a = 1;
  73. if a {
  74. print "a is 1";
  75. a = 2;
  76. }
  77. """))