diff --git a/CHANGES b/CHANGES index 3cda37d..8eba463 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,8 @@ Version 0.4 ----------- +05/09/2020 Changed the internal names used for EBNF rules to make them + a bit easier to debug in the parser.out file. + 03/06/2020 Added experimental support for EBNF repetition and optional syntax. For example, here is a rule for a comma-separated expression list: diff --git a/sly/yacc.py b/sly/yacc.py index 1bcf7f3..c7f0d99 100644 --- a/sly/yacc.py +++ b/sly/yacc.py @@ -1613,23 +1613,19 @@ def _replace_ebnf_optional(syms): # Generate grammar rules for repeated items _gencount = 0 -def _unique_names(names): - from collections import defaultdict, Counter - counts = Counter(names) - indices = defaultdict(int) - newnames = [] - for name in names: - if counts[name] == 1: - newnames.append(name) - else: - newnames.append(f'{name}{indices[name]}') - indices[name] += 1 - return newnames - # Dictionary mapping name aliases generated by EBNF rules. _name_aliases = { } +def _sanitize_symbols(symbols): + for sym in symbols: + if sym.startswith("'"): + yield str(hex(ord(sym[1]))) + elif sym.isidentifier(): + yield sym + else: + yield sym.encode('utf-8').hex() + def _generate_repeat_rules(symbols): ''' Symbols is a list of grammar symbols [ symbols ]. This @@ -1654,9 +1650,10 @@ def _generate_repeat_rules(symbols): ''' global _gencount _gencount += 1 - name = f'_{_gencount}_repeat' - oname = f'_{_gencount}_items' - iname = f'_{_gencount}_item' + basename = f'_{_gencount}_' + '_'.join(_sanitize_symbols(symbols)) + name = f'{basename}_repeat' + oname = f'{basename}_items' + iname = f'{basename}_item' symtext = ' '.join(symbols) _name_aliases[name] = symbols @@ -1709,7 +1706,8 @@ def _generate_optional_rules(symbols): ''' global _gencount _gencount += 1 - name = f'_{_gencount}_optional' + basename = f'_{_gencount}_' + '_'.join(_sanitize_symbols(symbols)) + name = f'{basename}_optional' symtext = ' '.join(symbols) _name_aliases[name] = symbols