You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

44 lines
1.1 KiB

#!/usr/bin/env python3
import sys
import re
def parse_rules(lines):
rules = {}
for line in lines:
rule, pattern = line.split(':')
alternatives = pattern.split('|')
rules[int(rule)] = [a.strip(' ').split(' ') for a in alternatives]
return rules
def memo(f):
mem = {}
def helper(x):
if x not in mem: mem[x] = f(x)
return mem[x]
return helper
@memo
def expr(rule):
if rule == 8:
return expr(42) + '+'
if rule == 11:
return '(?:' + expr(42) + '(?=a*(\1?+b)b*(\2?+c)))+\1' + expr(31) + ')'
global rules
if type(rule) is str:
try: rule = int(rule)
except ValueError: return rule[1]
pattern = rules[rule]
res = ["".join(expr(dep) for dep in alt) for alt in pattern]
if len(res) == 1: return res[0]
return "(" + "|".join(res) + ")"
if __name__ == '__main__':
rules, messages = open(sys.argv[1]).read().split('\n\n')
rules = parse_rules(rules.split('\n'))
count = 0
messages = messages.split("\n")
for m in messages:
if bool(re.match('^' + expr(0) + '$', m)):
count += 1
print(count)