pub const ISC_PARG: &str = "# Interscript ISC grammar \u{2014} portable .parg (parsanol grammar language).\n#\n# A 1:1 port of the canonical Ruby-DSL grammar in\n# lib/interscript/isc/grammar/concerns/*.rb (+ core.rb). Every rule in\n# this file carries a comment naming its concern rule of origin. The\n# port is semantic, not cosmetic \u{2014} the parsanol .parg surface has no\n# `.maybe`/`.repeat`/`.absent?` combinators, so they map as:\n#\n# Ruby .parg\n# ----------------------- --------------------------------\n# x.repeat(0) / repeat *x\n# x.repeat(1) 1*x\n# x.maybe [x]\n# x.absent? !x\n# x.present? &x\n# a | b a / b (ordered choice, PEG)\n# a >> b a b\n# expr.as(:name) (expr) as name\n#\n# Two semantics worth calling out because the corpus depends on them:\n#\n# * The Ruby DSL\'s `any` matches ANY character including raw newlines\n# (multiline `description { ... }` bodies parse). `chr` here is that\n# true any-character matcher. Wherever the concerns stop at a newline\n# they do it with an EXPLICIT newline.absent? \u{2014} mirrored verbatim\n# below (line_comment, field_raw, comment_item).\n# * Choice is ordered (PEG), exactly like the Ruby alternation \u{2014} the\n# alternative order below is copied verbatim from the concerns and is\n# load-bearing (item_atom, metadata_field, stage_item, ...).\n#\n# Consumed by tools/isc-parg-check (parsanol-rs validation harness).\n\ngrammar InterscriptIsc version \"1.0.0\" edition \"v1\" {\n\n ## Interscript ISC map language, ported from the Ruby-DSL concerns.\n\n # ---------------------------------------------------------------------\n # Concerns::Primitives \u{2014} whitespace, comments, identifiers, strings\n # ---------------------------------------------------------------------\n\n # The DSL\'s `any` \u{2014} every Unicode scalar value, raw newlines included.\n utf = %x00-10FFFF\n chr = utf\n\n # rule(:newline) \u{2014} \"\\n\" | \"\\r\\n\" | \"\\r\"\n newline = %x0A / %x0D.0A / %x0D\n\n # rule(:line_comment) \u{2014} \"#\" >> (newline.absent? >> any).repeat\n # (stops at CR too \u{2014} the absent? is on the full newline rule)\n line_comment = \"#\" *(!newline chr)\n\n # rule(:space) \u{2014} /\\s/ is [ \\t\\r\\n\\f\\v]\n space = 1*(%x20 / %x09 / %x0A / %x0B / %x0C / %x0D)\n\n # rule(:whitespace) / rule(:whitespace?)\n whitespace = 1*(space / line_comment)\n wsq = [whitespace]\n\n # rule(:inline_space) / rule(:inline_whitespace) / inline_whitespace?\n inline_space = 1*(%x20 / %x09)\n inline_whitespace = 1*(inline_space / line_comment)\n iwsq = [inline_whitespace]\n\n # rule(:comma) \u{2014} \",\" with trailing whitespace allowed\n comma = \",\" [whitespace]\n\n # rule(:arrow) \u{2014} whitespace? >> \"->\" >> whitespace?\n arrow = [whitespace] \"->\" [whitespace]\n\n # rule(:identifier)\n ident_first = %x41-5A / %x61-7A / %x5F\n ident_rest = %x41-5A / %x61-7A / %x30-39 / %x5F\n identifier = (ident_first 0*ident_rest) as identifier\n\n # rule(:escape_sequence) \u{2014} the corpus rulings are in the concerns:\n # \\uXXXX (exactly 4), \\U with 4..8 hex (gki-bel \"\\U040E\"), and a lone\n # \\U (un-mar converter corruption).\n esc_nl = (\"n\") as newline\n esc_cr = (\"r\") as carriage_return\n esc_tab = (\"t\") as tab\n esc_dq = (%x22) as dquote\n esc_bs = (%x5C) as backslash\n esc_uni4 = \"u\" (4hexd) as unicode\n esc_uni = \"U\" (4*8hexd) as unicode\n esc_u_lone = (\"U\") as u_lone\n hexd = %x30-39 / %x41-46 / %x61-66\n escape_sequence = %x5C (esc_nl / esc_cr / esc_tab / esc_dq / esc_bs / esc_uni4 / esc_uni / esc_u_lone)\n\n # rule(:plain_run) \u{2014} escape-free stretch of a double-quoted string\n plain_run = (!%x22 !%x5C chr)\n\n # rule(:double_quoted_string) \u{2014} runs captured as slices\n dq_part = escape_sequence / (1*plain_run as run)\n double_quoted_string = %x22 (*(dq_part) as string) %x22\n\n # rule(:single_quoted_string) \u{2014} no escape interpretation\n single_quoted_string = %x27 (*( !%x27 chr ) as string) %x27\n\n # rule(:quoted_string)\n quoted_string = double_quoted_string / single_quoted_string\n\n # braced(inner) is a Ruby method (scaffold), not a rule: every use\n # site below spells \"{\" [whitespace] inner [whitespace] \"}\" inline.\n\n # ---------------------------------------------------------------------\n # Concerns::Items \u{2014} item expressions\n # ---------------------------------------------------------------------\n\n # rule(:keyword) \u{2014} the concern\'s ordered list. One deviation, forced\n # by the parg compiler\'s shadow lint: \"any_character\" must precede\n # \"any\" (longest-first). Semantically identical \u{2014} keyword is used\n # only under negative lookahead, where any matching branch suffices.\n keyword = (\"parallel\" / \"sequence\" / \"stage\" / \"compose\" / \"separate\" / \"system\" / \"metadata\" / \"aliases\" / \"tests\" / \"notes\" / \"description\" / \"name\" / \"authority\" / \"dependency\" / \"run\" / \"sub\" / \"before\" / \"after\" / \"not_before\" / \"not_after\" / \"any_character\" / \"any\" / \"none\" / \"boundary\" / \"line_start\" / \"line_end\" / \"word_boundary\" / \"downcase\" / \"upcase\" / \"title_case\" / \"capture\" / \"maybe\" / \"some\" / \"ref\")\n\n # rule(:zero_width_primitive)\n zw_primitive = ((\"boundary\" / \"line_start\" / \"line_end\" / \"word_boundary\" / \"space\" / \"non_boundary\")) as primitive\n\n # rule(:function_call)\n fn_lit = ((\"upcase\" / \"downcase\" / \"title_case\" / \"reverse\" / \"strip\" / \"swapcase\")) as function\n\n # rule(:any_character)\n any_char_lit = (\"any_character\") as any_char\n\n # str(\"none\").as(:none)\n none_lit = (\"none\") as none\n\n # rule(:capture_reference) \u{2014} ref(N), single digit\n digit = %x30-39\n capture_reference = ((\"ref\" \"(\" [whitespace] (digit as digit) [whitespace] \")\")) as ref\n\n # rule(:alias_reference) \u{2014} identifier with optional .qualified part,\n # rejected when a keyword or followed by \"{\".\n alias_reference = ((!(keyword) identifier [(\".\" (identifier as qualified_name))] !\"{\")) as alias\n\n # rule(:range_arg)\n range_arg = ((quoted_string) as lo) [whitespace] \"..\" [whitespace] ((quoted_string) as hi)\n\n # rule(:set_arg) \u{2014} quoted single, or [ item, item, ... ]\n list_items = item 0*((comma / whitespace) item)\n set_arg = ((quoted_string) as single) / (\"[\" [whitespace] ((list_items) as list) [whitespace] \"]\")\n\n # rule(:alias_arg) \u{2014} bare alias inside any(...)\n alias_arg = ((!(zw_primitive) !(keyword) identifier)) as alias_ref\n\n # rule(:any_constructor)\n any_ctor = \"any\" \"(\" [whitespace] ((range_arg / set_arg / alias_arg / (item as any_item)) as any) [whitespace] \")\"\n\n # rule(:capture_constructor) / maybe / some\n capture_ctor = \"capture\" \"(\" [whitespace] ((item) as capture_inner) [whitespace] \")\"\n maybe_ctor = \"maybe\" \"(\" [whitespace] ((item) as maybe_inner) [whitespace] \")\"\n some_ctor = \"some\" \"(\" [whitespace] ((item) as some_inner) [whitespace] \")\"\n\n # rule(:item_atom) \u{2014} ordered exactly as the concern\n item_atom = quoted_string / none_lit / zw_primitive / any_char_lit / any_ctor / capture_ctor / maybe_ctor / some_ctor / fn_lit / capture_reference / alias_reference\n\n # rule(:item_continuation) \u{2014} lookahead only: not a block-rule keyword,\n # not `identifier =` (an alias declaration), and starts like an atom.\n item_atom_start = %x22 / %x27 / ident_first\n item_continuation = !(\"to\" / \"before\" / \"after\" / \"not_before\" / \"not_after\" / \"}\") (!(identifier [whitespace] \"=\") item_atom_start)\n\n # rule(:concat_sep) \u{2014} \"+\" with optional ws, or required whitespace\n concat_sep = ([whitespace] \"+\" [whitespace]) / whitespace\n\n # rule(:item) \u{2014} concatenation, one or more atoms\n item = ((item_atom 0*((concat_sep &(item_continuation)) item_atom))) as concatenation\n\n # ---------------------------------------------------------------------\n # Concerns::Items \u{2014} constraints\n # ---------------------------------------------------------------------\n\n # rule(:constraint) \u{2014} order verbatim: before | after | not_before | not_after\n constraint = (\"before\" whitespace ((item) as before)) / (\"after\" whitespace ((item) as after)) / (\"not_before\" whitespace ((item) as not_before)) / (\"not_after\" whitespace ((item) as not_after))\n\n # rule(:constraints) \u{2014} (whitespace >> constraint).repeat\n constraints = (*(whitespace constraint)) as constraints\n\n # ---------------------------------------------------------------------\n # Concerns::Stages \u{2014} rules, directives, stage bodies\n # ---------------------------------------------------------------------\n\n # rule(:compact_rule) \u{2014} from/to are single atoms\n compact_rule = \"sub\" whitespace ((item_atom) as from) whitespace ((item_atom) as to) constraints\n\n # rule(:block_rule) \u{2014} from/to are concatenations\n block_rule = \"sub\" [whitespace] \"{\" [whitespace] \"from\" whitespace ((item) as from) [whitespace] \"to\" whitespace ((item) as to) constraints [whitespace] \"}\"\n\n # rule(:rule) \u{2014} block | compact, ordered\n rule = block_rule / compact_rule\n\n # rule(:comment_item) \u{2014} strict parse: comments only, no stray\n # identifiers (WO87/A4 ruling).\n comment_item = (\"#\" *(!%x0A chr)) as comment\n\n # rule(:bare_rule) \u{2014} legacy .imp compatibility\n bare_rule = ((rule)) as bare_rule\n\n # rule(:sequence_block) / rule(:parallel_block)\n rule_line = [whitespace] (rule / comment_item) [whitespace]\n rule_items = *(rule_line)\n sequence_block = \"sequence\" [whitespace] \"{\" [whitespace] ((rule_items) as sequence) [whitespace] \"}\"\n parallel_block = \"parallel\" [whitespace] \"{\" [whitespace] ((rule_items) as parallel) [whitespace] \"}\"\n\n # rule(:separate_directive)\n separate_directive = ((\"separate\")) as separate [whitespace \"separator\" whitespace ((item_atom) as separator)]\n\n # rule(:string_case_directive) \u{2014} title_case takes optional kwargs\n kwarg = ((identifier) as kwarg_name) [whitespace] \":\" [whitespace] ((quoted_string) as kwarg_value)\n kwarg_list = ((kwarg) as kwarg) 0*((\",\" [whitespace]) ((kwarg) as kwarg))\n string_case_directive = ((\"downcase\" / \"upcase\")) as case / ((\"title_case\") as case [whitespace ((kwarg_list) as case_kwargs)])\n\n # rule(:compose_directive)\n compose_directive = ((\"compose\" / \"decompose\")) as compose\n\n # rule(:rababa_directive)\n rababa_directive = ((\"rababa\")) as funcall_name [whitespace ((kwarg_list) as funcall_kwargs)]\n\n # rule(:run_rule) \u{2014} map.<dep>.stage.<stage> | stage.<stage>\n run_rule = \"run\" whitespace ((\"map.\" ((identifier) as dep) \".stage.\" ((identifier) as stage)) / ((\"stage.\" ((identifier) as stage))) as run_stage_only)\n\n # rule(:stage_item) \u{2014} order verbatim\n stage_item = [whitespace] (sequence_block / parallel_block / run_rule / separate_directive / string_case_directive / compose_directive / rababa_directive / bare_rule / comment_item) [whitespace]\n stage_items = *(stage_item)\n\n # rule(:stage_block) \u{2014} stage(name) | stage name\n stage_block = \"stage\" (( \"(\" ((identifier) as stage_name) \")\" ) / (whitespace ((identifier) as stage_name))) [whitespace] \"{\" [whitespace] ((stage_items) as stage) [whitespace] \"}\"\n\n # ---------------------------------------------------------------------\n # Concerns::Tests\n # ---------------------------------------------------------------------\n\n # rule(:test_line)\n test_line = [whitespace] ((quoted_string) as input) arrow ((quoted_string) as expected) [(whitespace \"note\" whitespace ((quoted_string) as note))] [whitespace]\n test_items = *(test_line)\n tests_block = \"tests\" [whitespace] \"{\" [whitespace] ((test_items) as tests) [whitespace] \"}\"\n\n # ---------------------------------------------------------------------\n # Concerns::Metadata\n # ---------------------------------------------------------------------\n\n # rule(:raw_text)\n raw_text = *( %x5C \"{\" / %x5C \"}\" / (!\"}\" chr) )\n\n # rule(:description_field)\n description_field = \"description\" [whitespace] \"{\" [whitespace] ((raw_text) as description) [whitespace] \"}\"\n\n # rule(:relations_field) / relation_block / relation_type\n relation_type = \"supersedes\" / \"superseded_by\" / \"based_on\" / \"basis_for\" / \"alias_of\" / \"adopted_from\" / \"related_to\"\n relation_block = [whitespace] ((relation_type)) as type whitespace ((quoted_string)) as system [(whitespace \"note\" whitespace ((quoted_string) as note))] [whitespace]\n relations_block = \"relations\" [whitespace] \"{\" [whitespace] ((*(relation_block)) as relations) [whitespace] \"}\"\n\n # rule(:notes_field) / note_line\n note_line = [whitespace] \"note\" [whitespace] ((quoted_string) as note) [whitespace]\n notes_field = \"notes\" [whitespace] \"{\" [whitespace] ((*(note_line)) as notes) [whitespace] \"}\"\n\n # rule(:system_status_field) / code_status_field\n system_status_field = \"system_status\" whitespace ((\"current\" / \"former\" / \"inactive\")) as system_status\n code_status_field = \"code_status\" whitespace ((\"preferred\" / \"proposed\" / \"deprecated\")) as code_status\n\n # rule(:specification_field)\n spec_value = (quoted_string) as specification\n specification_field = \"specification\" whitespace ((spec_value 0*((comma) (spec_value))) as specification)\n\n # rule(:provenance_field)\n provenance_value = (quoted_string) as provenance\n provenance_field = \"provenance\" [whitespace] ((provenance_value 0*((comma) (provenance_value))) as provenance)\n\n # rule(:generic_field) / empty_field / field_value\n empty_field = (&newline / &\"}\")\n field_raw = 1*(!newline !\"}\" !\"{\" chr)\n field_value = ((quoted_string / field_raw)) as field_value\n field_block = \"{\" [whitespace] ((raw_text) as field_block) [whitespace] \"}\"\n generic_field = ((identifier) as field_name) iwsq (empty_field / field_value / field_block)\n\n # rule(:metadata_field) \u{2014} order verbatim. The concern\'s dead rules\n # (authority_field, source/target_spelling_field, identifying_field,\n # name_field) are unreachable from metadata_field and are subsumed by\n # generic_field here; see grammar/ISC-PARG-GAPS.md.\n metadata_field = [whitespace] (description_field / relations_block / system_status_field / code_status_field / specification_field / notes_field / provenance_field / generic_field) [whitespace]\n metadata_items = *(metadata_field)\n metadata_block = \"metadata\" [whitespace] \"{\" [whitespace] ((metadata_items) as metadata) [whitespace] \"}\"\n\n # ---------------------------------------------------------------------\n # Concerns::Aliases\n # ---------------------------------------------------------------------\n\n # rule(:alias_decl)\n alias_decl = [whitespace] ((identifier) as name) [whitespace] \"=\" [whitespace] ((item) as value) [whitespace]\n alias_items = *(alias_decl)\n aliases_block = \"aliases\" [whitespace] \"{\" [whitespace] ((alias_items) as aliases) [whitespace] \"}\"\n\n # ---------------------------------------------------------------------\n # Concerns::Dependencies\n # ---------------------------------------------------------------------\n\n # rule(:dependency_decl)\n dependency_decl = \"dependency\" whitespace ((quoted_string) as target) [(whitespace \"as\" whitespace ((identifier) as alias))]\n\n # ---------------------------------------------------------------------\n # Concerns::System\n # ---------------------------------------------------------------------\n\n # rule(:block_item) \u{2014} order verbatim\n block_item = [whitespace] (metadata_block / aliases_block / tests_block / stage_block / dependency_decl) [whitespace]\n\n # rule(:system_block)\n system_block = \"system\" whitespace ((quoted_string) as system_code) [whitespace] \"{\" [whitespace] ((*(block_item)) as body) [whitespace] \"}\" [whitespace]\n\n # rule(:isc_source) \u{2014} root; !utf pins full-input consumption\n isc_source = [whitespace] ((system_block)) as system [whitespace] !utf\n\n entry isc: isc_source\n\n test isc {\n accept \"system \\\"T:a-b:c-d:1\\\" { stage main { parallel { sub \\\"a\\\" \\\"b\\\" } } }\"\n accept \"system \\\"T:a-b:c-d:1\\\" { metadata { } tests { } }\"\n accept \"system \\\"T:a-b:c-d:1\\\" { stage main { sub { from \\\"x\\\" to \\\"y\\\" before boundary } } }\"\n accept \"system \\\"T:a-b:c-d:1\\\" { stage main { sub { from \\\"e\\\" to \\\"f\\\" after any(\\\"aeiou\\\") } } }\"\n reject \"system \\\"T:a-b:c-d:1\\\" {\"\n reject \"system \\\"T:a-b:c-d:1\\\" { stage main { sub \\\"a\\\" } }\"\n reject \"system \\\"T:a-b:c-d:1\\\" { stage main { oops } }\"\n reject \"system \\\"T:a-b:c-d:1\\\" }\"\n }\n}\n";Expand description
Vendored verbatim from interscript-ruby@34bd8829 grammar/isc.parg
(introduced in WO13 commit 873caf2; blob c9d4ffc8).