class Grammar: def __init__(self, sourceName, ruleString=None): self.ruleDict = {} if not sourceName is None: ruleString = open(sourceName).read() self._parseRules(ruleString) def __str__(self): return "\n".join( map(str, reduce(operator.add, self.ruleDict.values()))) def _parseRules(self, ruleString): for rawRule in filter(operator.truth, map(str.strip, ruleString.split("\n"))): if rawRule.startswith("="): self._setStartSymbol(symbol.NonTerminal( rawRule[1:].strip())) else: self._addRule(Rule(rawRule)) def _addRule(self, rule): self.ruleDict.setdefault(rule.getLeft(), []).append(rule)
def _setStartSymbol(self, startSymbol): self.startSymbol = startSymbol def getRulesForNonTerm(self, nonTerm): return self.ruleDict.get(nonTerm, []) def getStartSymbol(self): try: return self.startSymbol except AttributeError: return None def deriveLeft(self, nonTerm, word, yieldRules=None): res = [] for rule in self.getRulesForNonTerm( nonTerm): if yieldRules: res.append((rule, rule.applyToLeftmost(word))) else: res.append(rule.applyToLeftmost(word)) return res
Das sieht fürchterlicher aus als es ist. Die grobe Struktur ist weiterhin die unserer alten, simplen Grammatikklasse. Wesentliche Neuerungen:
Ihr solltet euch wenigstens an den rötlich unterlegten Aufgaben versuchen
(1)
Geht den Code durch und versucht, zu verstehen, was da jeweils passiert. Im Anhang dieser Seite gibt es das ganze auch kommentiert.