c-next 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +726 -0
- package/bin/cnext.js +5 -0
- package/grammar/C.g4 +1112 -0
- package/grammar/CNext.g4 +817 -0
- package/grammar/CPP14Lexer.g4 +282 -0
- package/grammar/CPP14Parser.g4 +1072 -0
- package/package.json +85 -0
- package/src/analysis/DivisionByZeroAnalyzer.ts +378 -0
- package/src/analysis/FunctionCallAnalyzer.ts +526 -0
- package/src/analysis/InitializationAnalyzer.ts +725 -0
- package/src/analysis/NullCheckAnalyzer.ts +427 -0
- package/src/analysis/types/IDivisionByZeroError.ts +25 -0
- package/src/analysis/types/IFunctionCallError.ts +17 -0
- package/src/analysis/types/IInitializationError.ts +55 -0
- package/src/analysis/types/INullCheckError.ts +25 -0
- package/src/codegen/CodeGenerator.ts +7945 -0
- package/src/codegen/CommentExtractor.ts +240 -0
- package/src/codegen/CommentFormatter.ts +155 -0
- package/src/codegen/HeaderGenerator.ts +265 -0
- package/src/codegen/TypeResolver.ts +365 -0
- package/src/codegen/types/ECommentType.ts +10 -0
- package/src/codegen/types/IComment.ts +21 -0
- package/src/codegen/types/ICommentError.ts +15 -0
- package/src/codegen/types/TOverflowBehavior.ts +6 -0
- package/src/codegen/types/TParameterInfo.ts +13 -0
- package/src/codegen/types/TTypeConstants.ts +94 -0
- package/src/codegen/types/TTypeInfo.ts +22 -0
- package/src/index.ts +518 -0
- package/src/lib/IncludeDiscovery.ts +131 -0
- package/src/lib/InputExpansion.ts +121 -0
- package/src/lib/PlatformIODetector.ts +162 -0
- package/src/lib/transpiler.ts +439 -0
- package/src/lib/types/ITranspileResult.ts +80 -0
- package/src/parser/c/grammar/C.interp +338 -0
- package/src/parser/c/grammar/C.tokens +229 -0
- package/src/parser/c/grammar/CLexer.interp +415 -0
- package/src/parser/c/grammar/CLexer.tokens +229 -0
- package/src/parser/c/grammar/CLexer.ts +750 -0
- package/src/parser/c/grammar/CListener.ts +976 -0
- package/src/parser/c/grammar/CParser.ts +9663 -0
- package/src/parser/c/grammar/CVisitor.ts +626 -0
- package/src/parser/cpp/grammar/CPP14Lexer.interp +478 -0
- package/src/parser/cpp/grammar/CPP14Lexer.tokens +264 -0
- package/src/parser/cpp/grammar/CPP14Lexer.ts +848 -0
- package/src/parser/cpp/grammar/CPP14Parser.interp +492 -0
- package/src/parser/cpp/grammar/CPP14Parser.tokens +264 -0
- package/src/parser/cpp/grammar/CPP14Parser.ts +19961 -0
- package/src/parser/cpp/grammar/CPP14ParserListener.ts +2120 -0
- package/src/parser/cpp/grammar/CPP14ParserVisitor.ts +1354 -0
- package/src/parser/grammar/CNext.interp +340 -0
- package/src/parser/grammar/CNext.tokens +214 -0
- package/src/parser/grammar/CNextLexer.interp +374 -0
- package/src/parser/grammar/CNextLexer.tokens +214 -0
- package/src/parser/grammar/CNextLexer.ts +668 -0
- package/src/parser/grammar/CNextListener.ts +1020 -0
- package/src/parser/grammar/CNextParser.ts +9239 -0
- package/src/parser/grammar/CNextVisitor.ts +654 -0
- package/src/preprocessor/Preprocessor.ts +301 -0
- package/src/preprocessor/ToolchainDetector.ts +225 -0
- package/src/preprocessor/types/IPreprocessResult.ts +39 -0
- package/src/preprocessor/types/IToolchain.ts +27 -0
- package/src/project/FileDiscovery.ts +236 -0
- package/src/project/Project.ts +425 -0
- package/src/project/types/IProjectConfig.ts +64 -0
- package/src/symbols/CNextSymbolCollector.ts +326 -0
- package/src/symbols/CSymbolCollector.ts +457 -0
- package/src/symbols/CppSymbolCollector.ts +362 -0
- package/src/symbols/SymbolTable.ts +312 -0
- package/src/symbols/types/IConflict.ts +20 -0
- package/src/types/ESourceLanguage.ts +10 -0
- package/src/types/ESymbolKind.ts +20 -0
- package/src/types/ISymbol.ts +45 -0
package/grammar/CNext.g4
ADDED
|
@@ -0,0 +1,817 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* C-Next Grammar
|
|
3
|
+
* A safer C for embedded systems development
|
|
4
|
+
*
|
|
5
|
+
* Key differences from C:
|
|
6
|
+
* - Assignment: <- (not =)
|
|
7
|
+
* - Comparison: = (not ==)
|
|
8
|
+
* - No pointer syntax (* for dereference)
|
|
9
|
+
* - & is read-only (get address, cannot reassign)
|
|
10
|
+
* - Fixed-width types: u8, i32, f64, etc.
|
|
11
|
+
* - scope for organization (ADR-016)
|
|
12
|
+
* - struct for data containers (ADR-014)
|
|
13
|
+
* - register bindings for hardware
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
grammar CNext;
|
|
17
|
+
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// Parser Rules
|
|
20
|
+
// ============================================================================
|
|
21
|
+
|
|
22
|
+
// Entry point
|
|
23
|
+
program
|
|
24
|
+
: (includeDirective | preprocessorDirective)* declaration* EOF
|
|
25
|
+
;
|
|
26
|
+
|
|
27
|
+
// Include directives (passed through to generated C)
|
|
28
|
+
// Uses same syntax as C: #include <header.h> or #include "header.h"
|
|
29
|
+
includeDirective
|
|
30
|
+
: INCLUDE_DIRECTIVE
|
|
31
|
+
;
|
|
32
|
+
|
|
33
|
+
// Preprocessor directives (ADR-037)
|
|
34
|
+
// C-Next takes a safety-first approach:
|
|
35
|
+
// - #define FLAG (no value) - allowed for conditional compilation
|
|
36
|
+
// - #define FLAG value - ERROR, must use const
|
|
37
|
+
// - #define NAME(args) - ERROR, function macros forbidden
|
|
38
|
+
// - #pragma target NAME - set target platform (ADR-049)
|
|
39
|
+
preprocessorDirective
|
|
40
|
+
: defineDirective
|
|
41
|
+
| conditionalDirective
|
|
42
|
+
| pragmaDirective
|
|
43
|
+
;
|
|
44
|
+
|
|
45
|
+
defineDirective
|
|
46
|
+
: DEFINE_FLAG // Flag-only: #define PLATFORM
|
|
47
|
+
| DEFINE_WITH_VALUE // Error: #define SIZE 256
|
|
48
|
+
| DEFINE_FUNCTION // Error: #define MAX(a,b) ...
|
|
49
|
+
;
|
|
50
|
+
|
|
51
|
+
conditionalDirective
|
|
52
|
+
: IFDEF_DIRECTIVE
|
|
53
|
+
| IFNDEF_DIRECTIVE
|
|
54
|
+
| ELSE_DIRECTIVE
|
|
55
|
+
| ENDIF_DIRECTIVE
|
|
56
|
+
;
|
|
57
|
+
|
|
58
|
+
// ADR-049: Target platform pragma for code generation
|
|
59
|
+
pragmaDirective
|
|
60
|
+
: PRAGMA_TARGET
|
|
61
|
+
;
|
|
62
|
+
|
|
63
|
+
// Top-level declarations
|
|
64
|
+
declaration
|
|
65
|
+
: scopeDeclaration
|
|
66
|
+
| registerDeclaration
|
|
67
|
+
| structDeclaration
|
|
68
|
+
| enumDeclaration
|
|
69
|
+
| bitmapDeclaration
|
|
70
|
+
| functionDeclaration
|
|
71
|
+
| variableDeclaration
|
|
72
|
+
;
|
|
73
|
+
|
|
74
|
+
// ----------------------------------------------------------------------------
|
|
75
|
+
// Scope (ADR-016: Organization with visibility control)
|
|
76
|
+
// ----------------------------------------------------------------------------
|
|
77
|
+
scopeDeclaration
|
|
78
|
+
: 'scope' IDENTIFIER '{' scopeMember* '}'
|
|
79
|
+
;
|
|
80
|
+
|
|
81
|
+
scopeMember
|
|
82
|
+
: visibilityModifier? variableDeclaration
|
|
83
|
+
| visibilityModifier? functionDeclaration
|
|
84
|
+
| visibilityModifier? enumDeclaration
|
|
85
|
+
| visibilityModifier? bitmapDeclaration
|
|
86
|
+
| visibilityModifier? registerDeclaration
|
|
87
|
+
;
|
|
88
|
+
|
|
89
|
+
visibilityModifier
|
|
90
|
+
: 'private'
|
|
91
|
+
| 'public'
|
|
92
|
+
;
|
|
93
|
+
|
|
94
|
+
// ----------------------------------------------------------------------------
|
|
95
|
+
// Register Bindings (ADR-004: Type-safe hardware access)
|
|
96
|
+
// ----------------------------------------------------------------------------
|
|
97
|
+
registerDeclaration
|
|
98
|
+
: 'register' IDENTIFIER '@' expression '{' registerMember* '}'
|
|
99
|
+
;
|
|
100
|
+
|
|
101
|
+
registerMember
|
|
102
|
+
: IDENTIFIER ':' type accessModifier '@' expression ','?
|
|
103
|
+
;
|
|
104
|
+
|
|
105
|
+
accessModifier
|
|
106
|
+
: 'rw' // Read-Write
|
|
107
|
+
| 'ro' // Read-Only
|
|
108
|
+
| 'wo' // Write-Only
|
|
109
|
+
| 'w1c' // Write-1-to-Clear
|
|
110
|
+
| 'w1s' // Write-1-to-Set
|
|
111
|
+
;
|
|
112
|
+
|
|
113
|
+
// ----------------------------------------------------------------------------
|
|
114
|
+
// Struct (ADR-014: Data containers without methods)
|
|
115
|
+
// ----------------------------------------------------------------------------
|
|
116
|
+
structDeclaration
|
|
117
|
+
: 'struct' IDENTIFIER '{' structMember* '}'
|
|
118
|
+
;
|
|
119
|
+
|
|
120
|
+
structMember
|
|
121
|
+
: type IDENTIFIER arrayDimension* ';'
|
|
122
|
+
;
|
|
123
|
+
|
|
124
|
+
// ----------------------------------------------------------------------------
|
|
125
|
+
// Enum (ADR-017: Type-safe enums)
|
|
126
|
+
// ----------------------------------------------------------------------------
|
|
127
|
+
enumDeclaration
|
|
128
|
+
: 'enum' IDENTIFIER '{' enumMember (',' enumMember)* ','? '}'
|
|
129
|
+
;
|
|
130
|
+
|
|
131
|
+
enumMember
|
|
132
|
+
: IDENTIFIER ('<-' expression)?
|
|
133
|
+
;
|
|
134
|
+
|
|
135
|
+
// ----------------------------------------------------------------------------
|
|
136
|
+
// Bitmap (ADR-034: Portable bit-packed data types)
|
|
137
|
+
// ----------------------------------------------------------------------------
|
|
138
|
+
bitmapDeclaration
|
|
139
|
+
: bitmapType IDENTIFIER '{' bitmapMember (',' bitmapMember)* ','? '}'
|
|
140
|
+
;
|
|
141
|
+
|
|
142
|
+
bitmapType
|
|
143
|
+
: 'bitmap8' // 8 bits, backed by u8
|
|
144
|
+
| 'bitmap16' // 16 bits, backed by u16
|
|
145
|
+
| 'bitmap24' // 24 bits, backed by u32 (3 bytes)
|
|
146
|
+
| 'bitmap32' // 32 bits, backed by u32
|
|
147
|
+
;
|
|
148
|
+
|
|
149
|
+
bitmapMember
|
|
150
|
+
: IDENTIFIER ('[' INTEGER_LITERAL ']')? // FieldName or FieldName[N]
|
|
151
|
+
;
|
|
152
|
+
|
|
153
|
+
// ----------------------------------------------------------------------------
|
|
154
|
+
// Functions
|
|
155
|
+
// ----------------------------------------------------------------------------
|
|
156
|
+
functionDeclaration
|
|
157
|
+
: type IDENTIFIER '(' parameterList? ')' block
|
|
158
|
+
;
|
|
159
|
+
|
|
160
|
+
parameterList
|
|
161
|
+
: parameter (',' parameter)*
|
|
162
|
+
;
|
|
163
|
+
|
|
164
|
+
parameter
|
|
165
|
+
: constModifier? type IDENTIFIER arrayDimension*
|
|
166
|
+
;
|
|
167
|
+
|
|
168
|
+
constModifier
|
|
169
|
+
: 'const'
|
|
170
|
+
;
|
|
171
|
+
|
|
172
|
+
volatileModifier
|
|
173
|
+
: 'volatile'
|
|
174
|
+
;
|
|
175
|
+
|
|
176
|
+
// ADR-044: Overflow behavior modifier
|
|
177
|
+
overflowModifier
|
|
178
|
+
: 'clamp' // Saturating arithmetic (safe default)
|
|
179
|
+
| 'wrap' // Two's complement wrap (opt-in)
|
|
180
|
+
;
|
|
181
|
+
|
|
182
|
+
// ADR-049: Atomic modifier for ISR-safe variables
|
|
183
|
+
atomicModifier
|
|
184
|
+
: 'atomic'
|
|
185
|
+
;
|
|
186
|
+
|
|
187
|
+
arrayDimension
|
|
188
|
+
: '[' expression? ']'
|
|
189
|
+
;
|
|
190
|
+
|
|
191
|
+
// ----------------------------------------------------------------------------
|
|
192
|
+
// Variables (ADR-003: Static allocation, ADR-044: Overflow behavior, ADR-049: Atomic)
|
|
193
|
+
// ----------------------------------------------------------------------------
|
|
194
|
+
variableDeclaration
|
|
195
|
+
: atomicModifier? volatileModifier? constModifier? overflowModifier? type IDENTIFIER arrayDimension* ('<-' expression)? ';'
|
|
196
|
+
;
|
|
197
|
+
|
|
198
|
+
// ----------------------------------------------------------------------------
|
|
199
|
+
// Statements
|
|
200
|
+
// ----------------------------------------------------------------------------
|
|
201
|
+
block
|
|
202
|
+
: '{' statement* '}'
|
|
203
|
+
;
|
|
204
|
+
|
|
205
|
+
statement
|
|
206
|
+
: variableDeclaration
|
|
207
|
+
| assignmentStatement
|
|
208
|
+
| expressionStatement
|
|
209
|
+
| ifStatement
|
|
210
|
+
| whileStatement
|
|
211
|
+
| doWhileStatement
|
|
212
|
+
| forStatement
|
|
213
|
+
| switchStatement
|
|
214
|
+
| returnStatement
|
|
215
|
+
| criticalStatement // ADR-050: Critical sections
|
|
216
|
+
| block
|
|
217
|
+
;
|
|
218
|
+
|
|
219
|
+
// ADR-050: Critical section for atomic multi-variable operations
|
|
220
|
+
criticalStatement
|
|
221
|
+
: 'critical' block
|
|
222
|
+
;
|
|
223
|
+
|
|
224
|
+
// ADR-001: <- for assignment, with compound assignment operators
|
|
225
|
+
assignmentStatement
|
|
226
|
+
: assignmentTarget assignmentOperator expression ';'
|
|
227
|
+
;
|
|
228
|
+
|
|
229
|
+
assignmentOperator
|
|
230
|
+
: '<-' // Simple assignment
|
|
231
|
+
| '+<-' // Addition assignment
|
|
232
|
+
| '-<-' // Subtraction assignment
|
|
233
|
+
| '*<-' // Multiplication assignment
|
|
234
|
+
| '/<-' // Division assignment
|
|
235
|
+
| '%<-' // Modulo assignment
|
|
236
|
+
| '&<-' // Bitwise AND assignment
|
|
237
|
+
| '|<-' // Bitwise OR assignment
|
|
238
|
+
| '^<-' // Bitwise XOR assignment
|
|
239
|
+
| '<<<-' // Left shift assignment
|
|
240
|
+
| '>><-' // Right shift assignment
|
|
241
|
+
;
|
|
242
|
+
|
|
243
|
+
assignmentTarget
|
|
244
|
+
: globalArrayAccess // ADR-016: global.GPIO7.DR_SET[idx] (most specific first)
|
|
245
|
+
| globalMemberAccess // ADR-016: global.GPIO7.DR_SET
|
|
246
|
+
| globalAccess // ADR-016: global.value
|
|
247
|
+
| thisArrayAccess // ADR-016: this.GPIO7.DR_SET[idx] (most specific first)
|
|
248
|
+
| thisMemberAccess // ADR-016: this.GPIO7.DR_SET
|
|
249
|
+
| thisAccess // ADR-016: this.member access (must be before memberAccess)
|
|
250
|
+
| arrayAccess // Must be before memberAccess (both can match arr[i])
|
|
251
|
+
| memberAccess
|
|
252
|
+
| IDENTIFIER
|
|
253
|
+
;
|
|
254
|
+
|
|
255
|
+
// ADR-016: this.member for scope-local access in assignment targets
|
|
256
|
+
thisAccess
|
|
257
|
+
: 'this' '.' IDENTIFIER
|
|
258
|
+
;
|
|
259
|
+
|
|
260
|
+
// ADR-016: this.member.member for chained scope-local access
|
|
261
|
+
thisMemberAccess
|
|
262
|
+
: 'this' '.' IDENTIFIER ('.' IDENTIFIER)+
|
|
263
|
+
;
|
|
264
|
+
|
|
265
|
+
// ADR-016: this.member[idx] or this.member.member[idx] for scope-local array/bit access
|
|
266
|
+
thisArrayAccess
|
|
267
|
+
: 'this' '.' IDENTIFIER '[' expression ']' // this.arr[i]
|
|
268
|
+
| 'this' '.' IDENTIFIER '[' expression ',' expression ']' // this.reg[offset, width]
|
|
269
|
+
| 'this' '.' IDENTIFIER ('.' IDENTIFIER)+ '[' expression ']' // this.GPIO7.DR_SET[i]
|
|
270
|
+
| 'this' '.' IDENTIFIER ('.' IDENTIFIER)+ '[' expression ',' expression ']' // this.GPIO7.ICR1[6, 2]
|
|
271
|
+
;
|
|
272
|
+
|
|
273
|
+
// ADR-016: global.member for global access in assignment targets
|
|
274
|
+
globalAccess
|
|
275
|
+
: 'global' '.' IDENTIFIER
|
|
276
|
+
;
|
|
277
|
+
|
|
278
|
+
globalMemberAccess
|
|
279
|
+
: 'global' '.' IDENTIFIER ('.' IDENTIFIER)+
|
|
280
|
+
;
|
|
281
|
+
|
|
282
|
+
globalArrayAccess
|
|
283
|
+
: 'global' '.' IDENTIFIER '[' expression ']' // global.arr[i]
|
|
284
|
+
| 'global' '.' IDENTIFIER ('.' IDENTIFIER)+ '[' expression ']' // global.GPIO7.DR_SET[i]
|
|
285
|
+
;
|
|
286
|
+
|
|
287
|
+
expressionStatement
|
|
288
|
+
: expression ';'
|
|
289
|
+
;
|
|
290
|
+
|
|
291
|
+
ifStatement
|
|
292
|
+
: 'if' '(' expression ')' statement ('else' statement)?
|
|
293
|
+
;
|
|
294
|
+
|
|
295
|
+
whileStatement
|
|
296
|
+
: 'while' '(' expression ')' statement
|
|
297
|
+
;
|
|
298
|
+
|
|
299
|
+
// ADR-027: Do-while with MISRA-compliant boolean condition (E0701)
|
|
300
|
+
doWhileStatement
|
|
301
|
+
: 'do' block 'while' '(' expression ')' ';'
|
|
302
|
+
;
|
|
303
|
+
|
|
304
|
+
forStatement
|
|
305
|
+
: 'for' '(' forInit? ';' expression? ';' forUpdate? ')' statement
|
|
306
|
+
;
|
|
307
|
+
|
|
308
|
+
// For loop init - uses versions without trailing semicolons
|
|
309
|
+
forInit
|
|
310
|
+
: forVarDecl
|
|
311
|
+
| forAssignment
|
|
312
|
+
;
|
|
313
|
+
|
|
314
|
+
// Variable declaration without trailing semicolon (for use in for loops)
|
|
315
|
+
forVarDecl
|
|
316
|
+
: atomicModifier? volatileModifier? overflowModifier? type IDENTIFIER arrayDimension* ('<-' expression)?
|
|
317
|
+
;
|
|
318
|
+
|
|
319
|
+
// Assignment without trailing semicolon (for use in for loops)
|
|
320
|
+
forAssignment
|
|
321
|
+
: assignmentTarget assignmentOperator expression
|
|
322
|
+
;
|
|
323
|
+
|
|
324
|
+
forUpdate
|
|
325
|
+
: assignmentTarget assignmentOperator expression
|
|
326
|
+
;
|
|
327
|
+
|
|
328
|
+
returnStatement
|
|
329
|
+
: 'return' expression? ';'
|
|
330
|
+
;
|
|
331
|
+
|
|
332
|
+
// ----------------------------------------------------------------------------
|
|
333
|
+
// Switch Statement (ADR-025: Safe switch with MISRA compliance)
|
|
334
|
+
// ----------------------------------------------------------------------------
|
|
335
|
+
switchStatement
|
|
336
|
+
: 'switch' '(' expression ')' '{' switchCase+ defaultCase? '}'
|
|
337
|
+
;
|
|
338
|
+
|
|
339
|
+
switchCase
|
|
340
|
+
: 'case' caseLabel ('||' caseLabel)* block
|
|
341
|
+
;
|
|
342
|
+
|
|
343
|
+
// Case labels must be constant expressions (like C)
|
|
344
|
+
// No || ambiguity: logical OR isn't valid in constant context
|
|
345
|
+
caseLabel
|
|
346
|
+
: qualifiedType // Enum value: EState.IDLE
|
|
347
|
+
| IDENTIFIER // Const or enum member
|
|
348
|
+
| INTEGER_LITERAL
|
|
349
|
+
| HEX_LITERAL
|
|
350
|
+
| BINARY_LITERAL
|
|
351
|
+
| CHAR_LITERAL
|
|
352
|
+
;
|
|
353
|
+
|
|
354
|
+
defaultCase
|
|
355
|
+
: 'default' ('(' INTEGER_LITERAL ')')? block
|
|
356
|
+
;
|
|
357
|
+
|
|
358
|
+
// ----------------------------------------------------------------------------
|
|
359
|
+
// Expressions
|
|
360
|
+
// ----------------------------------------------------------------------------
|
|
361
|
+
expression
|
|
362
|
+
: ternaryExpression
|
|
363
|
+
;
|
|
364
|
+
|
|
365
|
+
// ADR-022: Ternary with required parentheses, no nesting (semantic check)
|
|
366
|
+
ternaryExpression
|
|
367
|
+
: '(' orExpression ')' '?' orExpression ':' orExpression // Ternary with required parens
|
|
368
|
+
| orExpression // Non-ternary path
|
|
369
|
+
;
|
|
370
|
+
|
|
371
|
+
orExpression
|
|
372
|
+
: andExpression ('||' andExpression)*
|
|
373
|
+
;
|
|
374
|
+
|
|
375
|
+
andExpression
|
|
376
|
+
: equalityExpression ('&&' equalityExpression)*
|
|
377
|
+
;
|
|
378
|
+
|
|
379
|
+
// ADR-001: = for equality comparison (not ==)
|
|
380
|
+
equalityExpression
|
|
381
|
+
: relationalExpression (('=' | '!=') relationalExpression)*
|
|
382
|
+
;
|
|
383
|
+
|
|
384
|
+
relationalExpression
|
|
385
|
+
: bitwiseOrExpression (('<' | '>' | '<=' | '>=') bitwiseOrExpression)*
|
|
386
|
+
;
|
|
387
|
+
|
|
388
|
+
bitwiseOrExpression
|
|
389
|
+
: bitwiseXorExpression ('|' bitwiseXorExpression)*
|
|
390
|
+
;
|
|
391
|
+
|
|
392
|
+
bitwiseXorExpression
|
|
393
|
+
: bitwiseAndExpression ('^' bitwiseAndExpression)*
|
|
394
|
+
;
|
|
395
|
+
|
|
396
|
+
bitwiseAndExpression
|
|
397
|
+
: shiftExpression ('&' shiftExpression)*
|
|
398
|
+
;
|
|
399
|
+
|
|
400
|
+
shiftExpression
|
|
401
|
+
: additiveExpression (('<<' | '>>') additiveExpression)*
|
|
402
|
+
;
|
|
403
|
+
|
|
404
|
+
additiveExpression
|
|
405
|
+
: multiplicativeExpression (('+' | '-') multiplicativeExpression)*
|
|
406
|
+
;
|
|
407
|
+
|
|
408
|
+
multiplicativeExpression
|
|
409
|
+
: unaryExpression (('*' | '/' | '%') unaryExpression)*
|
|
410
|
+
;
|
|
411
|
+
|
|
412
|
+
unaryExpression
|
|
413
|
+
: '!' unaryExpression
|
|
414
|
+
| '-' unaryExpression
|
|
415
|
+
| '~' unaryExpression
|
|
416
|
+
| '&' unaryExpression // Address-of (read-only, ADR-006)
|
|
417
|
+
| postfixExpression
|
|
418
|
+
;
|
|
419
|
+
|
|
420
|
+
postfixExpression
|
|
421
|
+
: primaryExpression postfixOp*
|
|
422
|
+
;
|
|
423
|
+
|
|
424
|
+
postfixOp
|
|
425
|
+
: '.' IDENTIFIER // Member access
|
|
426
|
+
| '[' expression ']' // Array subscript / single bit
|
|
427
|
+
| '[' expression ',' expression ']' // Bit range [start, width]
|
|
428
|
+
| '(' argumentList? ')' // Function call
|
|
429
|
+
;
|
|
430
|
+
|
|
431
|
+
primaryExpression
|
|
432
|
+
: sizeofExpression // ADR-023: sizeof operator
|
|
433
|
+
| castExpression
|
|
434
|
+
| structInitializer
|
|
435
|
+
| arrayInitializer // ADR-035: array initializers
|
|
436
|
+
| 'this' // ADR-016: scope-local reference
|
|
437
|
+
| 'global' // ADR-016: global reference
|
|
438
|
+
| IDENTIFIER
|
|
439
|
+
| literal
|
|
440
|
+
| '(' expression ')'
|
|
441
|
+
;
|
|
442
|
+
|
|
443
|
+
// ADR-023: Sizeof expression
|
|
444
|
+
// sizeof(type) or sizeof(expression)
|
|
445
|
+
sizeofExpression
|
|
446
|
+
: 'sizeof' '(' (type | expression) ')'
|
|
447
|
+
;
|
|
448
|
+
|
|
449
|
+
// ADR-017: Cast expression for enum to integer conversion
|
|
450
|
+
castExpression
|
|
451
|
+
: '(' type ')' unaryExpression
|
|
452
|
+
;
|
|
453
|
+
|
|
454
|
+
// Struct initializer: Point { x: 10, y: 20 } or inferred { x: 10, y: 20 }
|
|
455
|
+
structInitializer
|
|
456
|
+
: IDENTIFIER '{' fieldInitializerList? '}' // Explicit type: Point { x: 10 }
|
|
457
|
+
| '{' fieldInitializerList '}' // Inferred type: { x: 10 } (requires context)
|
|
458
|
+
;
|
|
459
|
+
|
|
460
|
+
fieldInitializerList
|
|
461
|
+
: fieldInitializer (',' fieldInitializer)* ','?
|
|
462
|
+
;
|
|
463
|
+
|
|
464
|
+
fieldInitializer
|
|
465
|
+
: IDENTIFIER ':' expression
|
|
466
|
+
;
|
|
467
|
+
|
|
468
|
+
// ADR-035: Array initializers with square brackets
|
|
469
|
+
// [1, 2, 3] for explicit values, [0*] for fill-all
|
|
470
|
+
arrayInitializer
|
|
471
|
+
: '[' arrayInitializerElement (',' arrayInitializerElement)* ','? ']' // List: [1, 2, 3]
|
|
472
|
+
| '[' expression '*' ']' // Fill-all: [0*]
|
|
473
|
+
;
|
|
474
|
+
|
|
475
|
+
arrayInitializerElement
|
|
476
|
+
: expression
|
|
477
|
+
| structInitializer // For struct arrays: [{ x: 1 }, { x: 2 }]
|
|
478
|
+
| arrayInitializer // For nested arrays: [[1,2], [3,4]]
|
|
479
|
+
;
|
|
480
|
+
|
|
481
|
+
memberAccess
|
|
482
|
+
: IDENTIFIER ('.' IDENTIFIER)+ ('[' expression ']')+ // ADR-036: screen.pixels[0][0]
|
|
483
|
+
| IDENTIFIER ('.' IDENTIFIER)+ '[' expression ',' expression ']' // GPIO7.DR[start, width]
|
|
484
|
+
| IDENTIFIER ('.' IDENTIFIER)+ // GPIO7.DR_SET
|
|
485
|
+
| IDENTIFIER ('[' expression ']')+ ('.' IDENTIFIER)+ // arr[i].field1.field2...
|
|
486
|
+
| IDENTIFIER (('[' expression ']') | ('.' IDENTIFIER))+ // arr[i].field[j].member... (any mix)
|
|
487
|
+
;
|
|
488
|
+
|
|
489
|
+
arrayAccess
|
|
490
|
+
: IDENTIFIER '[' expression ']' // Single element/bit
|
|
491
|
+
| IDENTIFIER '[' expression ',' expression ']' // Bit range [start, width]
|
|
492
|
+
;
|
|
493
|
+
|
|
494
|
+
argumentList
|
|
495
|
+
: expression (',' expression)*
|
|
496
|
+
;
|
|
497
|
+
|
|
498
|
+
// ----------------------------------------------------------------------------
|
|
499
|
+
// Types
|
|
500
|
+
// ----------------------------------------------------------------------------
|
|
501
|
+
type
|
|
502
|
+
: primitiveType
|
|
503
|
+
| stringType // ADR-045: Bounded strings
|
|
504
|
+
| scopedType // ADR-016: this.Type for scoped types
|
|
505
|
+
| qualifiedType // ADR-016: Scope.Type from outside scope
|
|
506
|
+
| userType
|
|
507
|
+
| arrayType
|
|
508
|
+
| genericType
|
|
509
|
+
| 'void'
|
|
510
|
+
;
|
|
511
|
+
|
|
512
|
+
// ADR-016: Scoped type reference (this.State -> Motor_State)
|
|
513
|
+
scopedType
|
|
514
|
+
: 'this' '.' IDENTIFIER
|
|
515
|
+
;
|
|
516
|
+
|
|
517
|
+
// ADR-016: Qualified type from outside scope (Motor.State -> Motor_State)
|
|
518
|
+
qualifiedType
|
|
519
|
+
: IDENTIFIER '.' IDENTIFIER
|
|
520
|
+
;
|
|
521
|
+
|
|
522
|
+
primitiveType
|
|
523
|
+
: 'u8' | 'u16' | 'u32' | 'u64' // Unsigned integers
|
|
524
|
+
| 'i8' | 'i16' | 'i32' | 'i64' // Signed integers
|
|
525
|
+
| 'f32' | 'f64' // Floating point
|
|
526
|
+
| 'bool' // Boolean
|
|
527
|
+
| 'ISR' // ADR-040: Interrupt Service Routine function pointer
|
|
528
|
+
;
|
|
529
|
+
|
|
530
|
+
userType
|
|
531
|
+
: IDENTIFIER
|
|
532
|
+
;
|
|
533
|
+
|
|
534
|
+
// ADR-045: Bounded string type
|
|
535
|
+
// string<N> where N is character capacity (not including null terminator)
|
|
536
|
+
stringType
|
|
537
|
+
: 'string' '<' INTEGER_LITERAL '>' // Sized: string<64>
|
|
538
|
+
| 'string' // Unsized: for const inference
|
|
539
|
+
;
|
|
540
|
+
|
|
541
|
+
arrayType
|
|
542
|
+
: primitiveType '[' expression ']'
|
|
543
|
+
| userType '[' expression ']'
|
|
544
|
+
;
|
|
545
|
+
|
|
546
|
+
genericType
|
|
547
|
+
: IDENTIFIER '<' typeArgument (',' typeArgument)* '>'
|
|
548
|
+
;
|
|
549
|
+
|
|
550
|
+
typeArgument
|
|
551
|
+
: type
|
|
552
|
+
| expression // For numeric type parameters like buffer sizes
|
|
553
|
+
;
|
|
554
|
+
|
|
555
|
+
// ----------------------------------------------------------------------------
|
|
556
|
+
// Literals (ADR-024: Type suffixes OPTIONAL, validated against target type)
|
|
557
|
+
// ----------------------------------------------------------------------------
|
|
558
|
+
literal
|
|
559
|
+
: SUFFIXED_DECIMAL // 42u8, 1000i32 (explicit type)
|
|
560
|
+
| SUFFIXED_HEX // 0xFFu16 (explicit type)
|
|
561
|
+
| SUFFIXED_BINARY // 0b1010u8 (explicit type)
|
|
562
|
+
| SUFFIXED_FLOAT // 3.14f32 (explicit type)
|
|
563
|
+
| INTEGER_LITERAL // 42 (type inferred from context, validated to fit)
|
|
564
|
+
| HEX_LITERAL // 0xFF (type inferred from context)
|
|
565
|
+
| BINARY_LITERAL // 0b1010 (type inferred from context)
|
|
566
|
+
| FLOAT_LITERAL // 3.14 (type inferred from context)
|
|
567
|
+
| STRING_LITERAL
|
|
568
|
+
| CHAR_LITERAL
|
|
569
|
+
| 'true'
|
|
570
|
+
| 'false'
|
|
571
|
+
| 'null'
|
|
572
|
+
| 'NULL' // ADR-047: C library NULL for interop
|
|
573
|
+
;
|
|
574
|
+
|
|
575
|
+
// ============================================================================
|
|
576
|
+
// Lexer Rules
|
|
577
|
+
// ============================================================================
|
|
578
|
+
|
|
579
|
+
// Preprocessor directives (passed through to C)
|
|
580
|
+
// Matches: #include <header.h> or #include "header.h"
|
|
581
|
+
INCLUDE_DIRECTIVE
|
|
582
|
+
: '#' [ \t]* 'include' [ \t]* ('<' ~[>\r\n]* '>' | '"' ~["\r\n]* '"')
|
|
583
|
+
;
|
|
584
|
+
|
|
585
|
+
// ADR-037: Preprocessor directive tokens
|
|
586
|
+
// Order matters: more specific patterns must come first
|
|
587
|
+
|
|
588
|
+
// Function-like macro (ERROR): #define NAME(
|
|
589
|
+
// Must check for '(' before value pattern
|
|
590
|
+
DEFINE_FUNCTION
|
|
591
|
+
: '#' [ \t]* 'define' [ \t]+ [a-zA-Z_] [a-zA-Z0-9_]* [ \t]* '(' ~[\r\n]*
|
|
592
|
+
;
|
|
593
|
+
|
|
594
|
+
// Define with value (ERROR): #define NAME value
|
|
595
|
+
// Has content after the identifier
|
|
596
|
+
DEFINE_WITH_VALUE
|
|
597
|
+
: '#' [ \t]* 'define' [ \t]+ [a-zA-Z_] [a-zA-Z0-9_]* [ \t]+ ~[\r\n]+
|
|
598
|
+
;
|
|
599
|
+
|
|
600
|
+
// Flag-only define (OK): #define NAME
|
|
601
|
+
// Just the identifier, nothing after (except whitespace/newline)
|
|
602
|
+
DEFINE_FLAG
|
|
603
|
+
: '#' [ \t]* 'define' [ \t]+ [a-zA-Z_] [a-zA-Z0-9_]* [ \t]*
|
|
604
|
+
;
|
|
605
|
+
|
|
606
|
+
// Conditional compilation directives (pass through)
|
|
607
|
+
IFDEF_DIRECTIVE
|
|
608
|
+
: '#' [ \t]* 'ifdef' [ \t]+ [a-zA-Z_] [a-zA-Z0-9_]* [ \t]*
|
|
609
|
+
;
|
|
610
|
+
|
|
611
|
+
IFNDEF_DIRECTIVE
|
|
612
|
+
: '#' [ \t]* 'ifndef' [ \t]+ [a-zA-Z_] [a-zA-Z0-9_]* [ \t]*
|
|
613
|
+
;
|
|
614
|
+
|
|
615
|
+
ELSE_DIRECTIVE
|
|
616
|
+
: '#' [ \t]* 'else' [ \t]*
|
|
617
|
+
;
|
|
618
|
+
|
|
619
|
+
ENDIF_DIRECTIVE
|
|
620
|
+
: '#' [ \t]* 'endif' [ \t]*
|
|
621
|
+
;
|
|
622
|
+
|
|
623
|
+
// ADR-049: Target platform pragma
|
|
624
|
+
// Matches: #pragma target teensy41, #pragma target cortex-m7, etc.
|
|
625
|
+
PRAGMA_TARGET
|
|
626
|
+
: '#' [ \t]* 'pragma' [ \t]+ 'target' [ \t]+ [a-zA-Z_] [a-zA-Z0-9_\-]*
|
|
627
|
+
;
|
|
628
|
+
|
|
629
|
+
// Keywords
|
|
630
|
+
SCOPE : 'scope';
|
|
631
|
+
STRUCT : 'struct';
|
|
632
|
+
ENUM : 'enum';
|
|
633
|
+
THIS : 'this'; // ADR-016: scope-local reference
|
|
634
|
+
GLOBAL : 'global'; // ADR-016: global reference
|
|
635
|
+
REGISTER : 'register';
|
|
636
|
+
PRIVATE : 'private';
|
|
637
|
+
PUBLIC : 'public';
|
|
638
|
+
CONST : 'const';
|
|
639
|
+
VOLATILE : 'volatile';
|
|
640
|
+
VOID : 'void';
|
|
641
|
+
IF : 'if';
|
|
642
|
+
ELSE : 'else';
|
|
643
|
+
WHILE : 'while';
|
|
644
|
+
DO : 'do'; // ADR-027: Do-while loops
|
|
645
|
+
FOR : 'for';
|
|
646
|
+
SWITCH : 'switch'; // ADR-025: Switch statements
|
|
647
|
+
CASE : 'case';
|
|
648
|
+
DEFAULT : 'default';
|
|
649
|
+
RETURN : 'return';
|
|
650
|
+
TRUE : 'true';
|
|
651
|
+
FALSE : 'false';
|
|
652
|
+
NULL : 'null';
|
|
653
|
+
C_NULL : 'NULL'; // ADR-047: C library NULL for interop
|
|
654
|
+
STRING : 'string'; // ADR-045: Bounded string type
|
|
655
|
+
SIZEOF : 'sizeof'; // ADR-023: Sizeof operator
|
|
656
|
+
|
|
657
|
+
// ADR-034: Bitmap type keywords
|
|
658
|
+
BITMAP8 : 'bitmap8';
|
|
659
|
+
BITMAP16 : 'bitmap16';
|
|
660
|
+
BITMAP24 : 'bitmap24';
|
|
661
|
+
BITMAP32 : 'bitmap32';
|
|
662
|
+
|
|
663
|
+
// Access modifiers for registers
|
|
664
|
+
RW : 'rw';
|
|
665
|
+
RO : 'ro';
|
|
666
|
+
WO : 'wo';
|
|
667
|
+
W1C : 'w1c';
|
|
668
|
+
W1S : 'w1s';
|
|
669
|
+
|
|
670
|
+
// Overflow behavior keywords (ADR-044)
|
|
671
|
+
CLAMP : 'clamp';
|
|
672
|
+
WRAP : 'wrap';
|
|
673
|
+
|
|
674
|
+
// ADR-049: Atomic types for ISR-safe variables
|
|
675
|
+
ATOMIC : 'atomic';
|
|
676
|
+
|
|
677
|
+
// ADR-050: Critical sections for multi-variable atomic operations
|
|
678
|
+
CRITICAL : 'critical';
|
|
679
|
+
|
|
680
|
+
// ADR-024: Type-suffixed numeric literals (REQUIRED)
|
|
681
|
+
// These MUST come before unsuffixed literals so ANTLR matches them first
|
|
682
|
+
// Suffixes: u8, u16, u32, u64, i8, i16, i32, i64, f32, f64
|
|
683
|
+
|
|
684
|
+
// Float with suffix: 3.14f32, 2.718f64, 1e10f64
|
|
685
|
+
SUFFIXED_FLOAT
|
|
686
|
+
: ([0-9]+ '.' [0-9]+ ([eE] [+-]? [0-9]+)? | [0-9]+ [eE] [+-]? [0-9]+) [fF] ('32' | '64')
|
|
687
|
+
;
|
|
688
|
+
|
|
689
|
+
// Hex with suffix: 0xFFu8, 0xDEADBEEFu32
|
|
690
|
+
SUFFIXED_HEX
|
|
691
|
+
: '0' [xX] [0-9a-fA-F]+ ([uUiI] ('8' | '16' | '32' | '64'))
|
|
692
|
+
;
|
|
693
|
+
|
|
694
|
+
// Binary with suffix: 0b1010u8, 0b11110000u8
|
|
695
|
+
SUFFIXED_BINARY
|
|
696
|
+
: '0' [bB] [01]+ ([uUiI] ('8' | '16' | '32' | '64'))
|
|
697
|
+
;
|
|
698
|
+
|
|
699
|
+
// Decimal integer with suffix: 42u8, 1000i32, 255u8
|
|
700
|
+
SUFFIXED_DECIMAL
|
|
701
|
+
: [0-9]+ ([uUiI] ('8' | '16' | '32' | '64'))
|
|
702
|
+
;
|
|
703
|
+
|
|
704
|
+
// Primitive types
|
|
705
|
+
U8 : 'u8';
|
|
706
|
+
U16 : 'u16';
|
|
707
|
+
U32 : 'u32';
|
|
708
|
+
U64 : 'u64';
|
|
709
|
+
I8 : 'i8';
|
|
710
|
+
I16 : 'i16';
|
|
711
|
+
I32 : 'i32';
|
|
712
|
+
I64 : 'i64';
|
|
713
|
+
F32 : 'f32';
|
|
714
|
+
F64 : 'f64';
|
|
715
|
+
BOOL : 'bool';
|
|
716
|
+
ISR_TYPE : 'ISR'; // ADR-040: Interrupt Service Routine type
|
|
717
|
+
|
|
718
|
+
// Operators
|
|
719
|
+
// Compound assignment operators (must be before simple operators for correct matching)
|
|
720
|
+
LSHIFT_ASSIGN : '<<<-'; // Left shift assignment
|
|
721
|
+
RSHIFT_ASSIGN : '>><-'; // Right shift assignment
|
|
722
|
+
PLUS_ASSIGN : '+<-'; // Addition assignment
|
|
723
|
+
MINUS_ASSIGN : '-<-'; // Subtraction assignment
|
|
724
|
+
STAR_ASSIGN : '*<-'; // Multiplication assignment
|
|
725
|
+
SLASH_ASSIGN : '/<-'; // Division assignment
|
|
726
|
+
PERCENT_ASSIGN : '%<-'; // Modulo assignment
|
|
727
|
+
BITAND_ASSIGN : '&<-'; // Bitwise AND assignment
|
|
728
|
+
BITOR_ASSIGN : '|<-'; // Bitwise OR assignment
|
|
729
|
+
BITXOR_ASSIGN : '^<-'; // Bitwise XOR assignment
|
|
730
|
+
|
|
731
|
+
// Simple operators
|
|
732
|
+
ASSIGN : '<-';
|
|
733
|
+
EQ : '=';
|
|
734
|
+
NEQ : '!=';
|
|
735
|
+
LT : '<';
|
|
736
|
+
GT : '>';
|
|
737
|
+
LTE : '<=';
|
|
738
|
+
GTE : '>=';
|
|
739
|
+
PLUS : '+';
|
|
740
|
+
MINUS : '-';
|
|
741
|
+
STAR : '*';
|
|
742
|
+
SLASH : '/';
|
|
743
|
+
PERCENT : '%';
|
|
744
|
+
AND : '&&';
|
|
745
|
+
OR : '||';
|
|
746
|
+
NOT : '!';
|
|
747
|
+
BITAND : '&';
|
|
748
|
+
BITOR : '|';
|
|
749
|
+
BITXOR : '^';
|
|
750
|
+
BITNOT : '~';
|
|
751
|
+
LSHIFT : '<<';
|
|
752
|
+
RSHIFT : '>>';
|
|
753
|
+
|
|
754
|
+
// Punctuation
|
|
755
|
+
LPAREN : '(';
|
|
756
|
+
RPAREN : ')';
|
|
757
|
+
LBRACE : '{';
|
|
758
|
+
RBRACE : '}';
|
|
759
|
+
LBRACKET : '[';
|
|
760
|
+
RBRACKET : ']';
|
|
761
|
+
SEMI : ';';
|
|
762
|
+
COMMA : ',';
|
|
763
|
+
DOT : '.';
|
|
764
|
+
DOTDOT : '..';
|
|
765
|
+
AT : '@';
|
|
766
|
+
COLON : ':';
|
|
767
|
+
|
|
768
|
+
// Note: BOOL_LITERAL handled by TRUE/FALSE tokens above
|
|
769
|
+
|
|
770
|
+
HEX_LITERAL
|
|
771
|
+
: '0' [xX] [0-9a-fA-F]+
|
|
772
|
+
;
|
|
773
|
+
|
|
774
|
+
BINARY_LITERAL
|
|
775
|
+
: '0' [bB] [01]+
|
|
776
|
+
;
|
|
777
|
+
|
|
778
|
+
FLOAT_LITERAL
|
|
779
|
+
: [0-9]+ '.' [0-9]+ ([eE] [+-]? [0-9]+)?
|
|
780
|
+
| [0-9]+ [eE] [+-]? [0-9]+
|
|
781
|
+
;
|
|
782
|
+
|
|
783
|
+
INTEGER_LITERAL
|
|
784
|
+
: [0-9]+
|
|
785
|
+
;
|
|
786
|
+
|
|
787
|
+
STRING_LITERAL
|
|
788
|
+
: '"' (~["\r\n\\] | '\\' .)* '"'
|
|
789
|
+
;
|
|
790
|
+
|
|
791
|
+
CHAR_LITERAL
|
|
792
|
+
: '\'' (~['\r\n\\] | '\\' .) '\''
|
|
793
|
+
;
|
|
794
|
+
|
|
795
|
+
// Identifiers
|
|
796
|
+
IDENTIFIER
|
|
797
|
+
: [a-zA-Z_] [a-zA-Z0-9_]*
|
|
798
|
+
;
|
|
799
|
+
|
|
800
|
+
// Comments - preserved on HIDDEN channel for output (ADR-043)
|
|
801
|
+
// DOC_COMMENT must be before LINE_COMMENT (ANTLR matches first rule that fits)
|
|
802
|
+
DOC_COMMENT
|
|
803
|
+
: '///' ~[\r\n]* -> channel(HIDDEN)
|
|
804
|
+
;
|
|
805
|
+
|
|
806
|
+
LINE_COMMENT
|
|
807
|
+
: '//' ~[\r\n]* -> channel(HIDDEN)
|
|
808
|
+
;
|
|
809
|
+
|
|
810
|
+
BLOCK_COMMENT
|
|
811
|
+
: '/*' .*? '*/' -> channel(HIDDEN)
|
|
812
|
+
;
|
|
813
|
+
|
|
814
|
+
// Whitespace
|
|
815
|
+
WS
|
|
816
|
+
: [ \t\r\n]+ -> skip
|
|
817
|
+
;
|