Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 50 additions & 13 deletions src/rfc3987_syntax/syntax_helpers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from lark import Lark, ParseTree, exceptions

from functools import partial
from pathlib import Path

from lark import Lark, ParseTree, exceptions

from rfc3987_syntax.utils import load_grammar

RFC3987_SYNTAX_PARSER_TYPE: str = "earley"
Expand All @@ -12,7 +13,7 @@
"absolute_iri",
"scheme",
"irelative_ref",
"irelative_part"
"irelative_part",
"ihier_part",
"iauthority",
"iuserinfo",
Expand Down Expand Up @@ -45,9 +46,52 @@
"pct_encoded",
]

# All start rules needed by validators
ALL_START_RULES: list[str] = [
"iri",
"iri_reference",
"absolute_iri",
"irelative_ref",
"irelative_part",
"ihier_part",
"iauthority",
"iuserinfo",
"ihost",
"ireg_name",
"ipath",
"ipath_abempty",
"ipath_absolute",
"ipath_noscheme",
"ipath_rootless",
"ipath_empty",
"isegment",
"isegment_nz",
"isegment_nz_nc",
"ipchar",
"iquery",
"ifragment",
"iunreserved",
"ucschar",
"iprivate",
"sub_delims",
"ip_literal",
"ipvfuture",
"ipv6address",
"h16",
"ls32",
"ipv4address",
"dec_octet",
"unreserved",
"alpha",
"digit",
"hexdig",
"port",
]

grammar: str = load_grammar(RFC3987_SYNTAX_GRAMMAR_PATH)

syntax_parser = Lark(grammar, start=["iri", "iri_reference", "absolute_iri"], parser=RFC3987_SYNTAX_PARSER_TYPE)
# Single shared parser with all start rules
syntax_parser = Lark(grammar, start=ALL_START_RULES, parser=RFC3987_SYNTAX_PARSER_TYPE)


def parse(term: str, value: str) -> ParseTree:
Expand All @@ -63,16 +107,9 @@ def is_valid_syntax(term: str, value: str):


def make_syntax_validator(rule_name):
parser = Lark(grammar, start=rule_name, parser=RFC3987_SYNTAX_PARSER_TYPE)

def syntax_validator(text):
try:
parser.parse(text)
return True
except exceptions.LarkError:
return False
"""Create a validator using the shared parser."""

return syntax_validator
return partial(is_valid_syntax, term=rule_name)


is_valid_syntax_iri = make_syntax_validator("iri")
Expand Down