Skip to content

Rule declaration

Yuriy edited this page May 13, 2025 · 2 revisions

You can declare either token or rule. Tokens are created during lexing phase and are independent parts of your grammar that the parser later distinguish. Rules consists of tokens. This means everything located in rule except reference to another rule must be token. So even if you place string, character sequence or else into rule it will be automatically changed to tokens.

Rule/token declaration

NAMESPACE: 
   'namespace'
;
TYPE:
 'var' | 'int' | 'bool' 
;
declaration_or_type:
  NAMESPACE | TYPE
;

Here NAMESPACE and TYPE are tokens because they are fully uppercase. declaration_or_type is rule because it is not fully uppercase. Note: Ab is still considered rule because having at least one uppercase character.

What can be inside production

A production may have

  • String literal: 'foo' (auto tokenized)
  • Character sequence group: [a-zA-Z]
  • Group: ("foo" | "bar")*
  • Optional group: "foo" | "bar"
  • Escaped character: \s
  • nospace character (says to not skip spaces in between of these rules) \s0
  • hex character: 0x01
  • binary character: 0b00000001

Quantifiers

Quantifiers let you specify how the particular rule should be matched. ? - match optionally. In other words 0 or 1 times

    • match 0 or more times
    • match 1 or more times

Nested rules

Nested rules are rules inside another rule. For example:

    #CSEQUENCE:
        '[' @ '^'? @ ( #ESCAPE | #SYMBOL | #DIAPASON )* ']'
        @{_not, val}
        #SYMBOL:
            @('\\' | '\\]' | [^\]])
            {@}
        ;
        #ESCAPE:
            // some escape chars like \s, \d
            '\\' \s0 @ (.)
            {@}
        ;
        #DIAPASON:
            ( @ SYMBOL \s0 '-' \s0 @ SYMBOL)
            @{from, to}
        ;
    ;

nested rule is declared with '#' in another rule, and referenced with #. Note that # only referce to nested rule in current rule. If you want refer nested rule of same level inside another nested rule you shouldn't use '#'. For example:

#member:

        @(keyvalue | value)? @ name | group | CSEQUENCE | STRING | HEX | BIN | NOSPACE | ESCAPED | ANY | OP | LINEAR_COMMENT | cll @ quantifier?

        @{ prefix, val, quantifier }
    ;
    #name:
        @ '#'? @ ID ('.' @ ID)*

        @{ is_nested, name, nested_name }
    ;

If you need to refer nested rule of another rule, use '.'. For example i need to refer rule::member::name

foo: 
    rule.member.name
;

Clone this wiki locally