Glossary:
- syntax - definition of some syntactical construct allowed in language
- Sequential syntax - syntax that match sub-syntaxes one after another
- Alternative syntax - syntax that match one of the subsyntaxes
- Extensible syntax - syntax to which more alternatives can be added externally. Extensible sequential syntax is represented as extensible alternative syntax with exactly one alternative defined.
- Sealed syntax - syntax that cannot be extended (default)
- Nested syntax - syntax nested into some other syntax. It is purely name resolution and scoping construct, it doesn't influence formal grammar/parsing. Useful for defining subsyntax used in a number of alternatives, decomposing complex rules, etc.
- QSN - Qualified Syntax Name, full name of the syntax including namespace, module name, and all outer syntax names down to parent, and own short name.
- FQN - Fully Qualified Name, full name for CLR type, e.g. AST node type, includes namespace, outer type names, and own short name.
See Node type generation for more information on QSN and FQN.
Code Block |
---|
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
Code Block |
---|
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
Code Block |
---|
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:
Code Block |
---|
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?
Code Block |
---|
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);",")*) "}"; |