diff --git a/lab3_First and Follow b/lab3_First and Follow new file mode 100644 index 0000000000000000000000000000000000000000..4b2ecfc308994e79ec796207af9464e0b2383af5 --- /dev/null +++ b/lab3_First and Follow @@ -0,0 +1,76 @@ +def is_terminal(symbol): + return symbol.islower() + +def first(grammar, symbol): + if is_terminal(symbol): + return {symbol} + result = set() + for rule in grammar[symbol]: + first_sym = rule[0] + if first_sym != symbol: + temp_result = first(grammar, first_sym) + result |= temp_result - {'e'} + if '{e}' in first(grammar, first_sym): + if len(rule) > 1: + result |= first(grammar, rule[1]) + else: + result.add('{e}') + return result + +def follow(grammar, symbol, start_symbol): + result = set() + if symbol == start_symbol: + result.add('$') + for lhs, rules in grammar.items(): + for rule in rules: + if symbol in rule: + index = rule.index(symbol) + if index < len(rule) - 1: + next_sym = rule[index + 1] + result |= first(grammar, next_sym) - {'{e}'} + if '{e}' in first(grammar, next_sym): + result |= follow(grammar, lhs, start_symbol) + else: + if lhs != symbol: + result |= follow(grammar, lhs, start_symbol) + return result + +def parse_grammar(grammar_str): + grammar = {} + defined_symbols = set() + for line in grammar_str.splitlines(): + line = line.strip() + if not line or line.startswith('{'): + continue + try: + lhs, rhs = line.split(':', 1) + except ValueError: + print(f"Error: Invalid rule format in line: {line}") + continue + defined_symbols.add(lhs.strip()) + rhs = rhs.strip(';').split('|') + for rule in rhs: + rule_symbols = rule.strip().split() + defined_symbols.update(rule_symbols) + grammar.setdefault(lhs.strip(), []).append(rule_symbols) + return grammar + +def main(): + grammar_str = """ + A : b C | B d; + B : C C | b A; + C : c C | {e}; + """ + grammar = parse_grammar(grammar_str) + start_symbol = 'A' + print("FIRST sets:") + for symbol, rules in grammar.items(): + for rule in rules: + print(f"first[{symbol}:{''.join(rule)}] = {first(grammar, rule[0])}") + + print("\nFOLLOW sets:") + for symbol in grammar: + print(f"follow[{symbol}] = {follow(grammar, symbol, start_symbol)}") + +if __name__ == "__main__": + main()