import random
def scrapelect():
return [[statement_list]]
def statement_list():
return [[statement, statement_list]]
def statement():
return [[randid(), ":", rvalue, filter_list, ";"]]
def rvalue():
return [[element], [leaf]]
def element():
return [[maybe_url, selector_list, selector_ops, "{", statement_list, "}"]]
def maybe_url():
return [[variable], [randstr()]]
def selector_list():
return [[selector, selector2]]
def selector():
return [[".", randid()], ["#", randid()], [randid()], ["*"]]
def selector2():
return [[selector_combinator, selector, selector2]]
def selector_combinator():
return [[x] for x in [" + ", " > ", " ~ ", ""]]
def selector_ops():
return [["?"], ["[]"]]
def filter_list():
return [["|", randid(), "(", arg_list, ")", filter_list]]
def arg_list():
return [[randid(), ":", leaf, arg_list2]]
def arg_list2():
return [[",", arg_list]]
def leaf():
return [[variable], [randflt()], [randstr()], [randint()]]
def variable():
return [["$", randid()]]
e = lambda: ""
def randid():
return "".join(random.choice("abcdefghjiklmnopqrstuvwxyz") for _ in range(random.randint(1, 26)))
def randflt():
return str((1 - random.random()) * 10000)
def randint():
return str(random.randint(-10000, 10000))
def randstr():
return f'"{randid()}"'
bases = {
statement_list,
maybe_url,
selector2,
selector_combinator,
selector_ops,
filter_list,
arg_list,
arg_list2
}
def fuzz(recurse_prob, f=scrapelect, a=None):
if a is None: a = recurse_prob
if f in bases:
r = random.random()
if r < 1 - recurse_prob:
yield ""
return
rule = random.choice(f())
for r in rule:
if isinstance(r, str):
yield r
else:
yield "".join(fuzz(recurse_prob * a, f=r))
if __name__ == '__main__':
import sys
r = float(sys.argv[1])
for x in fuzz(r): print(x)