common.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. from copy import deepcopy
  2. import sys
  3. from types import ModuleType
  4. from typing import Callable, Collection, Dict, Optional, TYPE_CHECKING, List
  5. if TYPE_CHECKING:
  6. from .lark import PostLex
  7. from .lexer import Lexer
  8. from .grammar import Rule
  9. from typing import Union, Type
  10. from typing import Literal
  11. if sys.version_info >= (3, 10):
  12. from typing import TypeAlias
  13. else:
  14. from typing_extensions import TypeAlias
  15. from .utils import Serialize
  16. from .lexer import TerminalDef, Token
  17. ###{standalone
  18. _ParserArgType: 'TypeAlias' = 'Literal["earley", "lalr", "cyk", "auto"]'
  19. _LexerArgType: 'TypeAlias' = 'Union[Literal["auto", "basic", "contextual", "dynamic", "dynamic_complete"], Type[Lexer]]'
  20. _LexerCallback = Callable[[Token], Token]
  21. ParserCallbacks = Dict[str, Callable]
  22. class LexerConf(Serialize):
  23. __serialize_fields__ = 'terminals', 'ignore', 'g_regex_flags', 'use_bytes', 'lexer_type'
  24. __serialize_namespace__ = TerminalDef,
  25. terminals: Collection[TerminalDef]
  26. re_module: ModuleType
  27. ignore: Collection[str]
  28. postlex: 'Optional[PostLex]'
  29. callbacks: Dict[str, _LexerCallback]
  30. g_regex_flags: int
  31. skip_validation: bool
  32. use_bytes: bool
  33. lexer_type: Optional[_LexerArgType]
  34. strict: bool
  35. def __init__(self, terminals: Collection[TerminalDef], re_module: ModuleType, ignore: Collection[str]=(), postlex: 'Optional[PostLex]'=None,
  36. callbacks: Optional[Dict[str, _LexerCallback]]=None, g_regex_flags: int=0, skip_validation: bool=False, use_bytes: bool=False, strict: bool=False):
  37. self.terminals = terminals
  38. self.terminals_by_name = {t.name: t for t in self.terminals}
  39. assert len(self.terminals) == len(self.terminals_by_name)
  40. self.ignore = ignore
  41. self.postlex = postlex
  42. self.callbacks = callbacks or {}
  43. self.g_regex_flags = g_regex_flags
  44. self.re_module = re_module
  45. self.skip_validation = skip_validation
  46. self.use_bytes = use_bytes
  47. self.strict = strict
  48. self.lexer_type = None
  49. def _deserialize(self):
  50. self.terminals_by_name = {t.name: t for t in self.terminals}
  51. def __deepcopy__(self, memo=None):
  52. return type(self)(
  53. deepcopy(self.terminals, memo),
  54. self.re_module,
  55. deepcopy(self.ignore, memo),
  56. deepcopy(self.postlex, memo),
  57. deepcopy(self.callbacks, memo),
  58. deepcopy(self.g_regex_flags, memo),
  59. deepcopy(self.skip_validation, memo),
  60. deepcopy(self.use_bytes, memo),
  61. )
  62. class ParserConf(Serialize):
  63. __serialize_fields__ = 'rules', 'start', 'parser_type'
  64. rules: List['Rule']
  65. callbacks: ParserCallbacks
  66. start: List[str]
  67. parser_type: _ParserArgType
  68. def __init__(self, rules: List['Rule'], callbacks: ParserCallbacks, start: List[str]):
  69. assert isinstance(start, list)
  70. self.rules = rules
  71. self.callbacks = callbacks
  72. self.start = start
  73. ###}