Glossary:

syntax File // this rule is not extensible, because all rules are sealed by default
{
  s Value !Any

  extensible syntax Value // this rule can be extended by using File.Value qualified name, it hides outer Value rule inside File
  {
    | Object // alternatives start with bar
    | Array
  }
}

extensible syntax Value // this is extensible alternative rule
{
  | Identifier 
  | String 
  | Number 
  | Object 
  | Array 
  | "true" 
  | "false" 
  | "null"
}

syntax Array // this is sequence rule, non-extensible
{
  "[" (Value; "," sm)* "]"
}

syntax Object // sequence rule
{
  "{" inl Properties = (Property; "," nl)* nl d "}" // and this rule is not extensible

  extensible syntax Property // nested rule declaration, can only be used inside Object without qualifier
  {
    Name sm ":" sm Value

    // since it is extensible sequence syntax, it is implicitly alternative syntax, so there is implicit "|" here
    extensible syntax Name // this rule is extensible
    {
      | String
      | Identifier
    }
  }
}

Examples of nested rule extensions

extend syntax File.Value
{
 | String; // make it possible to have single string in json file
}

extend syntax PropName = Object.Property.Name
{
 | Number; // make it possible to use numbers as keys in json map
}

Short version of the same syntax

syntax File = s Value=(Object | Array) !Any
syntax Value = Identifier | String | Number | Object | Array | "true" | "false" | "null";
syntax Array = "[" (Value; "," sm)*  "]";
syntax Object = "{" inl Properties nl d "}"
{
  syntax Property = Name=(String | Identifier) sm ":" sm Value;
  syntax Properties = (Property; "," nl)*;
}

Object declaration in short form above can be inlined:

syntax Object = "{" inl Properties=((Property=(Name=(String | Identifier) sm ":" sm Value); "," nl)*) nl d "}";

But it is hardly more readable... Or like this one-liner which is all the same except pretty-printing?

syntax File=Value=(Object|Array) !Any;syntax Value=Identifier|String|Number|Object|Array|"true"|"false"|"null";syntax Array="[" (Value; ",")* "]";syntax Object="{" Properties=((Property=(Name=(String|Identifier) ":" Value);",")*) "}";