github.com/nevalang/neva@v0.23.1-0.20240507185603-7696a9bb8dda/internal/compiler/parser/neva.g4 (about) 1 grammar neva; 2 3 prog: (NEWLINE | COMMENT | stmt)* EOF; 4 5 /* PARSER */ 6 7 stmt: 8 importStmt 9 | typeStmt 10 | interfaceStmt 11 | constStmt 12 | compStmt; 13 14 // Compiler Directives 15 compilerDirectives: (compilerDirective NEWLINE)+; 16 compilerDirective: '#' IDENTIFIER compilerDirectivesArgs?; 17 compilerDirectivesArgs: 18 '(' compiler_directive_arg (',' compiler_directive_arg)* ')'; 19 compiler_directive_arg: IDENTIFIER+; 20 21 // Imports 22 importStmt: 'import' NEWLINE* '{' NEWLINE* importDef* '}'; 23 importDef: importAlias? importPath ','? NEWLINE*; 24 importAlias: IDENTIFIER; 25 importPath: (importPathMod ':')? importPathPkg; 26 importPathMod: '@' | importMod; 27 importMod: IDENTIFIER (importModeDelim IDENTIFIER)*; 28 importModeDelim: '/' | '.'; 29 importPathPkg: IDENTIFIER ('/' IDENTIFIER)*; 30 31 // Entity Reference 32 entityRef: importedEntityRef | localEntityRef; 33 localEntityRef: IDENTIFIER; 34 importedEntityRef: pkgRef '.' entityName; 35 pkgRef: IDENTIFIER; 36 entityName: IDENTIFIER; 37 38 // Types 39 typeStmt: singleTypeStmt | groupTypeStmt; 40 singleTypeStmt: PUB_KW? 'type' typeDef; 41 groupTypeStmt: 42 'type' NEWLINE* '{' NEWLINE* (PUB_KW? typeDef NEWLINE*)* '}'; 43 typeDef: IDENTIFIER typeParams? typeExpr? COMMENT?; 44 typeParams: '<' NEWLINE* typeParamList? '>'; 45 typeParamList: typeParam (',' NEWLINE* typeParam)*; 46 typeParam: IDENTIFIER typeExpr? NEWLINE*; 47 typeExpr: typeInstExpr | typeLitExpr | unionTypeExpr; 48 typeInstExpr: entityRef typeArgs?; 49 typeArgs: 50 '<' NEWLINE* typeExpr (',' NEWLINE* typeExpr)* NEWLINE* '>'; 51 typeLitExpr: enumTypeExpr | structTypeExpr; 52 enumTypeExpr: 53 'enum' NEWLINE* '{' NEWLINE* IDENTIFIER ( 54 ',' NEWLINE* IDENTIFIER 55 )* NEWLINE* '}'; 56 structTypeExpr: 57 'struct' NEWLINE* '{' NEWLINE* structFields? '}'; 58 structFields: structField (NEWLINE+ structField)*; 59 structField: IDENTIFIER typeExpr NEWLINE*; 60 unionTypeExpr: 61 nonUnionTypeExpr (NEWLINE* '|' NEWLINE* nonUnionTypeExpr)+; 62 nonUnionTypeExpr: 63 typeInstExpr 64 | typeLitExpr; // union inside union lead to mutual left recursion (not supported by ANTLR) 65 66 // interfaces 67 interfaceStmt: singleInterfaceStmt | groupInterfaceStmt; 68 singleInterfaceStmt: PUB_KW? 'interface' interfaceDef; 69 groupInterfaceStmt: 70 'interface' NEWLINE* '{' NEWLINE* (PUB_KW? interfaceDef)* '}'; 71 interfaceDef: 72 IDENTIFIER typeParams? inPortsDef outPortsDef NEWLINE*; 73 inPortsDef: portsDef; 74 outPortsDef: portsDef; 75 portsDef: 76 '(' (NEWLINE* | portDef? | portDef (',' portDef)*) ')'; 77 portDef: singlePortDef | arrayPortDef; 78 singlePortDef: NEWLINE* IDENTIFIER typeExpr? NEWLINE*; 79 arrayPortDef: NEWLINE* '[' IDENTIFIER ']' typeExpr? NEWLINE*; 80 81 // const 82 constStmt: singleConstStmt | groupConstStmt; 83 singleConstStmt: PUB_KW? 'const' constDef; 84 groupConstStmt: 85 'const' NEWLINE* '{' NEWLINE* (PUB_KW? constDef)* '}'; 86 constDef: 87 IDENTIFIER typeExpr '=' (entityRef | constLit) NEWLINE*; 88 constLit: 89 nil 90 | bool 91 | MINUS? INT 92 | MINUS? FLOAT 93 | STRING 94 | enumLit 95 | listLit 96 | structLit; 97 primitiveConstLit: 98 nil 99 | bool 100 | MINUS? INT 101 | MINUS? FLOAT 102 | STRING 103 | enumLit; 104 nil: 'nil'; 105 bool: 'true' | 'false'; 106 enumLit: entityRef '::' IDENTIFIER; 107 listLit: '[' NEWLINE* listItems? ']'; 108 listItems: 109 compositeItem 110 | compositeItem (',' NEWLINE* compositeItem NEWLINE*)*; 111 compositeItem: entityRef | constLit; 112 structLit: 113 '{' NEWLINE* structValueFields? '}'; // same for struct and map 114 structValueFields: 115 structValueField (',' NEWLINE* structValueField)*; 116 structValueField: IDENTIFIER ':' compositeItem NEWLINE*; 117 118 // components 119 compStmt: singleCompStmt | groupCompStmt; 120 singleCompStmt: compilerDirectives? PUB_KW? 'component' compDef; 121 groupCompStmt: 122 'component' NEWLINE* '{' NEWLINE* ( 123 (COMMENT NEWLINE*)* compilerDirectives? PUB_KW? compDef 124 )* '}'; 125 compDef: interfaceDef compBody? NEWLINE*; 126 compBody: 127 '{' 128 NEWLINE* 129 (COMMENT NEWLINE*)* 130 (compNodesDef NEWLINE*)? 131 (COMMENT NEWLINE*)* 132 (connDefList NEWLINE*)? 133 (COMMENT NEWLINE*)* 134 '}'; 135 136 // nodes 137 compNodesDef: 'nodes' NEWLINE* compNodesDefBody; 138 compNodesDefBody: 139 '{' NEWLINE* ((compNodeDef | COMMENT) ','? NEWLINE*)* '}'; 140 compNodeDef: compilerDirectives? IDENTIFIER? nodeInst; 141 nodeInst: 142 entityRef NEWLINE* typeArgs? errGuard? NEWLINE* nodeDIArgs?; 143 errGuard: '?'; 144 nodeDIArgs: compNodesDefBody; 145 146 // network 147 compNetDef: 'net' NEWLINE* compNetBody; 148 compNetBody: '{' NEWLINE* connDefList? NEWLINE* '}'; 149 connDefList: (connDef | COMMENT) (NEWLINE* (connDef | COMMENT))*; 150 connDef: normConnDef | arrBypassConnDef; 151 normConnDef: senderSide '->' receiverSide; 152 senderSide: singleSenderSide | multipleSenderSide; 153 multipleSenderSide: 154 '[' NEWLINE* singleSenderSide ( 155 ',' NEWLINE* singleSenderSide NEWLINE* 156 )* ']'; 157 arrBypassConnDef: singlePortAddr '=>' singlePortAddr; 158 singleSenderSide: (portAddr | senderConstRef | primitiveConstLit) structSelectors?; 159 receiverSide: 160 chainedNormConn 161 | singleReceiverSide 162 | multipleReceiverSide; 163 chainedNormConn: normConnDef; 164 deferredConn: '(' NEWLINE* connDef NEWLINE* ')'; 165 senderConstRef: '$' entityRef; 166 portAddr: 167 singlePortAddr 168 | arrPortAddr 169 | lonelySinglePortAddr 170 | lonelyArrPortAddr; 171 lonelySinglePortAddr: portAddrNode; 172 lonelyArrPortAddr: portAddrNode portAddrIdx; 173 singlePortAddr: portAddrNode? ':' portAddrPort; 174 arrPortAddr: portAddrNode? ':' portAddrPort portAddrIdx; 175 portAddrNode: IDENTIFIER; 176 portAddrPort: IDENTIFIER; 177 portAddrIdx: '[' INT ']'; 178 structSelectors: '.' IDENTIFIER ('.' IDENTIFIER)*; 179 singleReceiverSide: portAddr | deferredConn; 180 multipleReceiverSide: 181 '[' NEWLINE* singleReceiverSide ( 182 ',' NEWLINE* singleReceiverSide NEWLINE* 183 )* ']'; 184 185 /* LEXER */ 186 187 COMMENT: '//' ~( '\r' | '\n')*; 188 PUB_KW: 'pub'; 189 IDENTIFIER: LETTER (LETTER | INT)*; 190 fragment LETTER: [a-zA-Z_]; 191 INT: [0-9]+; // one or more integer digits 192 MINUS: '-'; 193 FLOAT: [0-9]* '.' [0-9]+; 194 STRING: '\'' .*? '\''; 195 NEWLINE: '\r'? '\n'; // `\r\n` on windows and `\n` on unix 196 WS: [ \t]+ -> channel(HIDDEN); // ignore whitespace