<commit_before>from . import grammar_strict as gs
from . import tokens
from . import dre
from parser.cfg import slr1_grammar
import parser.symbol
from . import lexer

# Erweiterungen:
#   - Konkatenation ohne Komma
#   - * statt +?
#   - Beliebiges Auslassen oder Hinzufügen von Klammern, unter der folgenden
#     Operatorenpräzedenz:  Unär >> Konkatenation >> Auswahl

'''Ungeklammertes unary-Symbol.'''
class Unary(gs.Unary):
    def child(self):
        return self.production[0]

'''Ungeklammertes nary-Symbol.'''
class Nary(gs.Nary):
    def children(self):
        yield self.production[0]
        yield self.production[2]
        # TODO: Python 3.3+ erlaubt 'yield from'.
        for x in self.production[3].children():
            yield x

'''Klammerausdruck'''
class Paren(gs.Expr):
    def dre(self):
        return self.production[1].dre()

'''Sternausdruck'''
class OptPlus(Unary):
    def dre(self):
        return dre.Optional(dre.Plus(self.child().dre()))

# Durch Mehrfachvererbung überschreiben diese Operatoren in den strikten
# Operatoren nur die child() bzw. children() Funktion.
class Optional(Unary, gs.Optional):
    pass
class Plus(Unary, gs.Plus):
    pass
class Concat(Nary, gs.Concat):
    pass
class Choice(Nary, gs.Choice):
    pass

# Optionaler Komma-Delimiter.
class ConcatDelim(parser.symbol.NonTerm):
    pass

# Expr kann jede Form haben.
# Expr2 ist innerhalb eines Choice-Ausdrucks und kann selbst kein Choice sein.
# Expr3 ist innerhalb einer Konkatenation oder einem unären Ausdruck und kann nur geklammert oder unär sein.
# Innerhalb einer Klammer steht wiederum ein beliebiger Expr-Ausdruck.
class Expr2(gs.Expr):
    pass
class Expr3(gs.Expr):
    pass

# *-Nichtterminal
class Star(parser.symbol.Term):
    pass

def build_grammar():
    productions = {
        gs.Expr : {(Choice,), (Expr2,)},
        Expr2 : {(Concat,), (Expr3,)},
        Expr3 : {(Paren,), (Optional,), (Plus,), (OptPlus,), (gs.TermExpr,)},
        Paren : {(tokens.LeftParen, gs.Expr, tokens.RightParen),},
        Choice : {(Expr2, tokens.Pipe, Expr2, gs.ChoiceRep)},
        gs.ChoiceRep : {(tokens.Pipe, Expr2, gs.ChoiceRep), ()},
        Concat : {(Expr3, ConcatDelim, Expr3, gs.ConcatRep)},
        gs.ConcatRep : {(ConcatDelim, Expr3, gs.ConcatRep), ()},
        OptPlus : {(Expr3, Star)},
        Plus : {(Expr3, tokens.PlusSign)},
        Optional : {(Expr3, tokens.Question)},
        ConcatDelim : {(tokens.Comma,), ()},
        gs.TermExpr : {(tokens.Terminal,)}
    }

    return parser.cfg.slr1_grammar(productions, start=gs.Expr)

def build_lexer():
    table = tokens.table.copy()
    table['*'] = Star

    return lexer.lexer(table, tokens.Terminal)<commit_msg>Parser-Erweiterung: Character group.<commit_after>from . import grammar_strict as gs
from . import tokens
from . import dre
from parser.cfg import slr1_grammar
import parser.symbol
from . import lexer

# Erweiterungen:
#   - Konkatenation ohne Komma
#   - * statt +?
#   - Beliebiges Auslassen oder Hinzufügen von Klammern, unter der folgenden
#     Operatorenpräzedenz:  Unär >> Konkatenation >> Auswahl

'''Ungeklammertes unary-Symbol.'''
class Unary(gs.Unary):
    def child(self):
        return self.production[0]

'''Ungeklammertes nary-Symbol.'''
class Nary(gs.Nary):
    def children(self):
        yield self.production[0]
        yield self.production[2]
        # TODO: Python 3.3+ erlaubt 'yield from'.
        for x in self.production[3].children():
            yield x

'''Klammerausdruck'''
class Paren(gs.Expr):
    def dre(self):
        return self.production[1].dre()

'''Sternausdruck'''
class OptPlus(Unary):
    def dre(self):
        return dre.Optional(dre.Plus(self.child().dre()))

# Durch Mehrfachvererbung überschreiben diese Operatoren in den strikten
# Operatoren nur die child() bzw. children() Funktion.
class Optional(Unary, gs.Optional):
    pass
class Plus(Unary, gs.Plus):
    pass
class Concat(Nary, gs.Concat):
    pass
class Choice(Nary, gs.Choice):
    pass

# Optionaler Komma-Delimiter.
class ConcatDelim(parser.symbol.NonTerm):
    pass

# Expr kann jede Form haben.
# Expr2 ist innerhalb eines Choice-Ausdrucks und kann selbst kein Choice sein.
# Expr3 ist innerhalb einer Konkatenation oder einem unären Ausdruck und kann nur geklammert oder unär sein.
# Innerhalb einer Klammer steht wiederum ein beliebiger Expr-Ausdruck.
class Expr2(gs.Expr):
    pass
class Expr3(gs.Expr):
    pass

# *-Nichtterminal
class Star(parser.symbol.Term):
    pass

class SquareOpen(parser.symbol.Term):
    pass
class SquareClose(parser.symbol.Term):
    pass
class CharGroup(gs.Expr):
    def dre(self):
        x = self.production[1].symbol
        z = []
        for i in range(1, len(x)-1):
            if x[i] == '-':
                z += [chr(a) for a in range(ord(x[i-1]), ord(x[i+1])+1)]
            else:
                z.append(x[-1])
        if len(x) > 1 and x[-2] != '-':
            z += x[-2:]
        return dre.Choice([dre.Terminal(a) for a in z])

def build_grammar():
    productions = {
        gs.Expr : {(Choice,), (Expr2,)},
        Expr2 : {(Concat,), (Expr3,)},
        Expr3 : {(Paren,), (Optional,), (Plus,), (OptPlus,), (gs.TermExpr,), (CharGroup,)},
        Paren : {(tokens.LeftParen, gs.Expr, tokens.RightParen),},
        Choice : {(Expr2, tokens.Pipe, Expr2, gs.ChoiceRep)},
        gs.ChoiceRep : {(tokens.Pipe, Expr2, gs.ChoiceRep), ()},
        Concat : {(Expr3, ConcatDelim, Expr3, gs.ConcatRep)},
        gs.ConcatRep : {(ConcatDelim, Expr3, gs.ConcatRep), ()},
        OptPlus : {(Expr3, Star)},
        CharGroup : {(SquareOpen, tokens.Terminal, SquareClose)},
        Plus : {(Expr3, tokens.PlusSign)},
        Optional : {(Expr3, tokens.Question)},
        ConcatDelim : {(tokens.Comma,), ()},
        gs.TermExpr : {(tokens.Terminal,)}
    }

    return parser.cfg.slr1_grammar(productions, start=gs.Expr)

def build_lexer():
    table = tokens.table.copy()
    table['*'] = Star
    table['['] = SquareOpen
    table[']'] = SquareClose

    return lexer.lexer(table, tokens.Terminal)
{'fraction_non_alphanumeric': 0.1410383597883598, 'fraction_numerical': 0.01025132275132275, 'mean_word_length': 3.143150684931507, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7223107', 'n_tokens_mistral': 2159, 'n_tokens_neox': 2120, 'n_words': 512}