Token files have .token extension.
| token‑file | → | token‑collection‑declaration |
| token‑collection‑declaration | → | tokens token‑collection‑name { ( token‑declaration ( , token‑declaration )* )? } |
| token‑collection‑name | → | qualified‑id |
| token‑declaration | → | ( token‑name , token‑description‑string ) |
| token‑name | → | identifier |
| token‑description‑string | → | string‑literal |
Keyword files have .keyword extension.
| keyword‑file | → | imports keyword‑collection‑declaration |
| keyword‑collection‑declaration | → | keywords keyword‑collection‑name { ( keyword‑declaration ( , keyword‑declaration )* )? } |
| keyword‑collection‑name | → | qualified‑id |
| keyword‑declaration | → | ( keyword‑string , keyword‑token‑name ) |
| keyword‑string | → | string‑literal |
| keyword‑token‑name | → | identifier |
Expression files have .expr extension.
| expression‑file | → | expression‑collection‑declaration |
| expression‑collection‑declaration | → | expressions expression‑collection‑name { expression‑declaration * } |
| expression‑collection‑name | → | qualified‑id |
| expression‑declaration | → | expression‑name = regular‑expression‑string ; |
| expression‑name | → | identifier |
| regular‑expression | → | re‑choice |
| re‑choice | → | catenation ( | catenation )* |
| catenation | → | repetition + |
| repetition | → | re‑primary ( * | + | ? )? |
| re‑primary | → | ( re‑choice ) | escape | class | expression‑reference | ^ | - | . | [ ^\x0\r\n{}\\()[\]|*+?.^- ] |
| class | → | [ ^ ? range * ] |
| range | → | char ( - char )? |
| char | → | ( | ) | [ | ] | | | * | + | ? | . | escape | ^ | - | [ ^\x0\r\n{}\\()[\]|*+?.^- ] |
| expression‑reference | → | { re‑expression‑name } |
| re‑expression‑name | → | [ ^\x0\r\n{}\\()[\]|*+?.^- ]+ |
Lexer files have .lexer extension.
| lexer‑file | → | export‑module‑declaration imports lexer lexer‑name { lexer‑content‑declaration * } |
| lexer‑name | → | identifier |
| lexer‑content‑declaration | → | rules‑declaration | variables‑declaration | actions‑declaration |
| rules‑declaration | → | rules { rule‑declaration * } |
| rule‑declaration | → | regular‑expression‑string action ? rule‑body |
| action | → | $ ( action‑id ) |
| action‑id | → | integer‑literal |
| rule‑body | → | compound‑statement |
| variables‑declaration | → | variables { variable‑declaration * } |
| variable‑declaration | → | variable‑type variable‑name ; |
| variable‑type | → | type‑id |
| variable‑name | → | identifier |
| actions‑declaration | → | actions { action‑declaration * } |
| action‑declaration | → | action = action‑body |
| action‑body | → | compound‑statement |
Lexer project files have .slg extension.
| slg‑file | → | project slg‑project‑name slg‑file‑declaration * |
| slg‑project‑name | → | qualified‑id |
| slg‑file‑declaration | → | token‑file‑declaration | keyword‑file‑declaration | expression‑file‑declaration | lexer‑file‑declaration |
| token‑file‑declaration | → | extern ? tokens file‑path ; |
| keyword‑file‑declaration | → | keywords file‑path ; |
| expression‑file‑declaration | → | expressions file‑path ; |
| lexer‑file‑declaration | → | lexer file‑path ; |
Parser files have .parser extension.
| parser‑file | → | export‑module‑declaration imports parser‑declaration * |
| parser‑declaration | → | parser parser‑name { parser‑statement } |
| parser‑name | → | identifier |
| parser‑statement | → | lexer‑statement | main‑statement | using‑statement | parsing‑rule |
| lexer‑statement | → | lexer lexer‑type ; |
| lexer‑type | → | type‑id |
| main‑statement | → | main ; |
| using‑statement | → | using parser‑rule‑name ; |
| parser‑rule‑name | → | qualified‑id |
| parsing‑rule | → | parsing‑rule‑name parameters‑and‑variables return‑type ? ::= parsing‑rule‑body ; |
| parsing‑rule‑name | → | identifier |
| parameters‑and‑variables | → | ( ( param‑or‑var ( , param‑or‑var )* )? ) |
| param‑or‑var | → | parameter | variable |
| parameter | → | parameter‑type parameter‑declarator |
| parameter‑type | → | type‑id |
| parameter‑declarator | → | declarator |
| variable | → | var variable‑type variable‑declarator |
| variable‑type | → | type‑id |
| variable‑declarator | → | declarator |
| parsing‑rule‑body | → | parsing‑expression |
| parsing‑expression | → | choice |
| choice | → | sequence ( | sequence )* |
| sequence | → | difference + |
| difference | → | list ( - list )* |
| list | → | prefix ( % prefix )? |
| prefix | → | lookahead | postfix |
| lookahead | → | & postfix |
| postfix | → | primary ( kleene‑operator | positive‑operator | optional‑operator )? |
| kleene‑operator | → | * |
| positive‑operator | → | + |
| optional‑operator | → | ? |
| primary | → | ( rule‑call | primitive | grouping ) expectation‑operator ? actions ? |
| rule‑call | → | parsing‑rule‑name argument‑list ? : instance‑identifier |
| argument‑list | → | expression‑list |
| instance‑identifier | → | identifier |
| primitive | → | empty | any | token‑name | char‑literal | string‑literal |
| grouping | → | ( parsing‑expression ) |
| expectation‑operator | → | ! |
| actions | → | success‑action ( / failure‑action )? |
| success‑action | → | compound‑statement |
| failure‑action | → | compound‑statement |
A using statement imports a rule from another parser, so it can be used the same way as rules declared inside the currrent parser. The parser‑rule‑name is of the form PARSER_NAME.RULE_NAME .
Parsing rule body consists of parsing expressions .
The parsing‑rule‑name in a rule‑call is an identifier that refers to an existing rule in the same parser, or a rule in another parser that has been imported to the current parser using a using statement.
The instance‑identifier in a rule‑call gives a unique name for a called rule inside a body of a rule. You can invent any name as long as it conforms to identifier syntax. If a body of a rule contains more than one calls of the same rule, the instance identifier disambiguates between them. The instance identifier also allows one to refer to a return value of a rule.
Parser project files have .spg extension.
| spg‑file | → | project spg‑project‑name spg‑file‑declaration * |
| spg‑project‑name | → | qualified‑id |
| spg‑file‑declaration | → | token‑file‑declaration | parser‑file‑declaration |
| parser‑file‑declaration | → | extern ? parser file‑path ; |
| export‑module‑declaration | → | export module module‑name ; |
| imports | → | import * |
| import | → | import‑prefix ? import module‑name |
| import‑prefix | → | interface‑prefix | implementation‑prefix |
| interface‑prefix | → | [ interface ] |
| implementation‑prefix | → | [ implementation ] |
| module‑name | → | qualified‑id |
| file‑path | → | < [^ \n> ]* > |
| qualified‑id | → | identifier ( . identifier )* |
| identifier | → | Unicode identifier |
| regular‑expression‑string | → | string‑literal |
| string‑literal | → | " ( schar | escape )* " |
| schar | → | [^ \"\\\n\r ] |
| char‑literal | → | ' ( cchar | escape )+ ' |
| cchar | → | [^ '\\\n\r ] |
| escape | → |
\
( ( x | X ) hex‑digit + | ( d | D ) digit + | octal‑digit + | u hex4 | U hex8 | ( a | b | f | n | r | t | v |.)) |
| integer‑literal | → | octal‑literal | decimal‑literal | hex‑literal |
| floating‑literal | → | fraction exponent ? | digit + exponent |
| fraction | → | digit * . digit + | digit + . |
| exponent | → | ( e | E ) sign ? digit + |
| sign | → | + | - |
| decimal‑literal | → | [ 1-9 ] digit * |
| digit‑sequence | → | digit + |
| digit | → | [ 0-9 ] |
| hex‑literal | → | ( 0x | 0X ) hex‑digit + |
| hex8 | → | hex4 hex4 |
| hex4 | → | hex‑digit hex‑digit hex‑digit hex‑digit |
| hex‑digit | → | [ 0-9a-fA-F ] |
| octal‑literal | → | 0 octal‑digit * |
| octal‑digit | → | [ 0-7 ] |
| block‑declaration | → | namespace‑alias‑definition | using‑directive | using‑declaration | simple‑declaration |
| simple‑declaration | → | decl‑specifier‑seq ? init‑declarator‑list ? ; |
| decl‑specifier‑seq | → | decl‑specifier + | type‑name |
| decl‑specifier | → | storage‑class‑specifier | type‑specifier | typedef |
| storage‑class‑specifier | → | auto | register | static | extern | mutable |
| type‑specifier | → | simple‑type‑specifier | cv‑qualifier |
| simple‑type‑specifier | → | char | char8_t | char16_t | char32_t | wchar_t | bool | short | int | long | signed | unsigned | float | double | void |
| type‑name | → | qualified‑cpp‑id ( < template‑argument‑list > )? |
| template‑argument‑list | → | template‑argument ( , template‑argument )* |
| template‑argument | → | type‑id | assignment‑expression |
| typedef | → | typedef |
| cv‑qualifier | → | const | volatile |
| namespace‑alias‑definition | → | namespace cpp‑identifier = qualified‑cpp‑id ; |
| using‑declaration | → | using qualified‑cpp‑id ; |
| using‑directive | → | using namespace qualified‑cpp‑id ; |
| init‑declarator‑list | → | init‑declarator ( , init‑declarator )* |
| init‑declarator | → | declarator initializer ? |
| declarator | → | direct‑declarator | ptr‑operator declarator |
| direct‑declarator | → | declarator‑id ( [ constant‑expression ] | [ ] | ( declarator ) )* |
| declarator‑id | → | id‑expression | type‑name |
| type‑id | → | ( type‑specifier‑seq | type‑name ) abstract‑declarator ? |
| type‑specifier‑seq | → | type‑specifier + |
| abstract‑declarator | → | ptr‑operator abstract‑declarator ? | direct‑abstract‑declarator |
| direct‑abstract‑declarator | → | ( [ constant‑expression ] | [ ] | ( abstract‑declarator ) )+ |
| ptr‑operator | → | * cv‑qualifier‑seq ? | & |
| cv‑qualifier‑seq | → | cv‑qualifier + |
| initializer | → | = initializer‑clause | ( expression‑list ) |
| initializer‑clause | → | assignment‑expression | { initializer‑list } | { } |
| initializer‑list | → | initializer‑clause ( , initializer‑clause )* |
| expression | → | assignment‑expression ( , assignment‑expression )* |
| constant‑expression | → | expression |
| assignment‑expression | → | logical‑or‑expression asssignment‑op assignment‑expression | conditional‑expression | throw‑expression |
| assignment‑op | → | = | *= | /= | %= | += | -= | <<= | >>= | &= | ^= | |= |
| conditional‑expression | → | logical‑or‑expression ( ? expression : expression )? |
| throw‑expression | → | throw assignment‑expression ? |
| logical‑or‑expression | → | logical‑and‑expression ( || logical‑and‑expression )* |
| logical‑and‑expression | → | inclusive‑or‑expression ( && inclusive‑or‑expression )* |
| inclusive‑or‑expression | → | exclusive‑or‑expression ( | exclusive‑or‑expression )* |
| exclusive‑or‑expression | → | and‑expression ( ^ and‑expression )* |
| and‑expression | → | equality‑expression ( & equality‑expression )* |
| equality‑expression | → | relational‑expression ( eq‑op relational‑expression )* |
| eq‑op | → | == | != |
| relational‑expression | → | shift‑expression ( rel‑op shift‑expression )* |
| rel‑op | → | < | > | <= | >= |
| shift‑expression | → | additive‑expression ( shift‑op additive‑expression )* |
| shift‑op | → | << | >> |
| additive‑expression | → | multiplicative‑expression ( add‑op multiplicative‑expression )* |
| add‑op | → | + | - |
| multiplicative‑expression | → | pm‑expression ( mul‑op pm‑expression )* |
| mul‑op | → | * | / | % |
| pm‑expression | → | cast‑expression ( pm‑op cast‑expression )* |
| pm‑op | → | .* | ‑>* | |
| cast‑expression | → | ( ( type‑id ) cast‑expression ) | unary‑expression |
| unary‑expression | → | postfix‑expression | postcast‑expression | ++ unary‑expression | -- unary‑expression | unary‑op cast‑expression | sizeof ( type‑id ) | sizeof unary‑expression | new‑expression | delete‑expression |
| unary‑op | → | * | & | + | - | ! | ~ |
| postfix‑expression | → | primary‑expression ( [ expression ] | ( expression‑list ) | . id‑expression | ‑> id‑expression | ++ | -- )* |
| postcast‑expression | → | ( static_cast | dynamic_cast | const_cast | reinterpret_cast ) < type‑id > ( expression ) | typeid ( expression ) |
| expression‑list | → | assignment‑expression ( , assignment‑expression )* |
| primary‑expression | → | literal | this | ( expression ) | id‑expression |
| id‑expression | → | qualified‑cpp‑id :: operator‑function‑id | :: ? operator‑function‑id | qualified‑cpp‑id |
| new‑expression | → | :: ? new new‑placement ? ( new‑type‑id | ( type‑id ) ) new‑initializer ? |
| new‑placement | → | ( expression‑list ) |
| new‑type‑id | → | ( type‑specifier‑seq | type‑name ) new‑declarator ? |
| new‑declarator | → | ptr‑operator new‑declarator ? | direct‑new‑declarator |
| new‑initializer | → | ( expression‑list ? ) |
| direct‑new‑declarator | → | [ expression ] ( [ constant‑expression ] )* |
| delete‑expression | → | :: ? delete ( [ ] )? cast‑expression |
| operator‑function‑id | → | operator operator |
| operator | → | [] | () | ‑>* | ‑> | , | -- | ++ | || | && | <= | >= | != | <= | >= | == | <<= | >>= | << | >> | |= | &= | ^= | %= | /= | *= | -= | += | < | > | = | ! | ~ | & | ^ | | | % | / | * | - | + | new [] | delete [] | new | delete |
| cpp‑identifier | → | identifier |
| qualified‑cpp‑id | → | :: ? cpp‑identifier ( :: cpp‑identifier )* |
| literal | → | integer‑literal | floating‑literal | char‑literal | string‑literal | true | false | nullptr |