Commit 0a443e16 authored by Eckhart Arnold's avatar Eckhart Arnold
Browse files

refactoring gen_search_rule() finished, not yet fully tested

parent 65034de1
...@@ -2543,6 +2543,11 @@ class EBNFCompiler(Compiler): ...@@ -2543,6 +2543,11 @@ class EBNFCompiler(Compiler):
the set of symbols that are referred to in the definition the set of symbols that are referred to in the definition
of a particular symbol. of a particular symbol.
:ivar referred_by_directive: A set of symbols which are directly
referred to in a directive. It does not matter whether
these symbals are reachable (i.e. directly oder indirectly
referred to) from the root-symbol.
:ivar symbols: A mapping of symbol names to their usages (not :ivar symbols: A mapping of symbol names to their usages (not
their definition!) in the EBNF source. their definition!) in the EBNF source.
...@@ -2658,6 +2663,7 @@ class EBNFCompiler(Compiler): ...@@ -2658,6 +2663,7 @@ class EBNFCompiler(Compiler):
self.rules = OrderedDict() # type: OrderedDict[str, List[Node]] self.rules = OrderedDict() # type: OrderedDict[str, List[Node]]
self.referred_symbols_cache = dict() # type: Dict[str, FrozenSet[str]] self.referred_symbols_cache = dict() # type: Dict[str, FrozenSet[str]]
self.directly_referred_cache = dict() # type: Dict[str, FrozenSet[str]] self.directly_referred_cache = dict() # type: Dict[str, FrozenSet[str]]
self.referred_by_directive = set() # type: Set[str]
self.current_symbols = [] # type: List[Node] self.current_symbols = [] # type: List[Node]
self.cache_literal_symbols = None # type: Optional[Dict[str, str]] self.cache_literal_symbols = None # type: Optional[Dict[str, str]]
self.symbols = {} # type: Dict[str, List[Node]] self.symbols = {} # type: Dict[str, List[Node]]
...@@ -2826,13 +2832,12 @@ class EBNFCompiler(Compiler): ...@@ -2826,13 +2832,12 @@ class EBNFCompiler(Compiler):
return value return value
def gen_search_rule(self, symbol: str, nd: Node, kind: str) -> ReprType: def gen_search_rule(self, node: Node, nd: Node, kind: str) -> ReprType:
"""Generates a search rule, which can be either a string for simple """Generates a search rule, which can be either a string for simple
string search or a regular expression from the node's content. Returns string search or a regular expression from the node's content. Returns
an empty string in case the node is neither regexp nor literal. an empty string in case the node is neither regexp nor literal.
:param symbol: The symbol of the parser to which the definition of the :param node: The node of the directive
search rule is related
:param nd: The node containing the AST of the search rule :param nd: The node containing the AST of the search rule
:param kind: The kind of the search rule, which must be one of :param kind: The kind of the search rule, which must be one of
"resume", "skip", "error" "resume", "skip", "error"
...@@ -2850,17 +2855,25 @@ class EBNFCompiler(Compiler): ...@@ -2850,17 +2855,25 @@ class EBNFCompiler(Compiler):
elif nd.tag_name == 'procedure': elif nd.tag_name == 'procedure':
return unrepr(nd.content) return unrepr(nd.content)
elif nd.tag_name == 'symbol': elif nd.tag_name == 'symbol':
return unrepr(symbol) referred_symbol = nd.content.strip()
self.referred_by_directive.add(referred_symbol)
return unrepr(referred_symbol)
else: else:
pass # Add artificial symbol here! symbol = node[0].content.split('_')[0]
# in case of an arbitrary expression do the following: stub = f"{symbol}_{kind}_"
# 1. Create an artificial symbol "xxx_resume_1__ = ..." and postpone compilation L = len(stub)
# 2. Return the name of that symbol nr = 1
# 3. Compile when or just be assembling Python source code for rule in self.rules.keys():
return '' if rule[:L] == stub:
# self.tree.new_error(nd, 'Only regular expressions, string literals and external ' i = int(rule[L:].strip('_'))
# 'procedures are allowed as search rules, but not: ' + nd.tag_name) if i > nr: nr = i + 1
# return unrepr('') rule = stub + str(nr) + '__'
self.current_symbols = [node]
self.rules[rule] = self.current_symbols
defn = self.compile(nd)
assert defn.find("(") >= 0 # synonyms impossible here
self.definitions[rule] = defn
return unrepr(rule)
def directly_referred(self, symbol: str) -> FrozenSet[str]: def directly_referred(self, symbol: str) -> FrozenSet[str]:
...@@ -3164,6 +3177,9 @@ class EBNFCompiler(Compiler): ...@@ -3164,6 +3177,9 @@ class EBNFCompiler(Compiler):
remove_connections(str(related)) remove_connections(str(related))
remove_connections(self.root_symbol) remove_connections(self.root_symbol)
for symbol in self.referred_by_directive:
if symbol in defined_symbols:
remove_connections(symbol)
for leftover in defined_symbols: for leftover in defined_symbols:
self.tree.new_error(self.rules[leftover][0], self.tree.new_error(self.rules[leftover][0],
'Rule "%s" is not connected to parser root "%s" !' % 'Rule "%s" is not connected to parser root "%s" !' %
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment