本节用于记录在基础文法 BNF 之上为了代码高亮所做的扩展优化
支持 json5 的注释
{
"name": "John", // 支持注释
"age": 30e+10,
"address": {
"street": "123 Main St",
"city": "New York",
"state": "NY"
}
}
<external-declaration> ::= <function-definition>
| <declaration>
| <group>
| <statement>
添加 <group>
<statement>
以适配宏定义与开头的陈述语句. C 默认不支持 if for 作为陈述语句
x += 10;
for (int i=0;i<10;i++) {
x = 20;
}
if (x == 10) {
x = 20;
}
具体见 syntaxlight\parsers\c_parser.py 中的 _unknown_typedef_id_guess
static clock_t ticks = 10;
static clock_t *ticks = 10;
bool 为 C23 中引入, 但实在是太常见了, 一般都会 typedef int bool
bool x = 1;
<gnu-c-statement-extension> ::= (__asm__ | asm ) <asm-qualifiers> "(" <STRING>+ <OutputOperands >* ")"
<asm-qualifiers> ::= volatile
| inline
| goto
<OutputOperands> ::= ":" <STRING>? ( "(" <constant_expression> ")" ) ("," <STRING>? ( "(" <constant_expression> ")" ))*
void my_function() __attribute__((noreturn));
int my_printf(const char *format, ...) __attribute__((format(printf, 1, 2)));
int my_variable __attribute__((aligned(16)));
struct packed_struct {
int a;
char b;
} __attribute__((packed));
typedef int my_int __attribute__((aligned(4)));
static inline uint64
r_fp()
{
uint64 x;
asm volatile("mv %0, s0" : "=r" (x) );
return x;
}
typedef uint64 unsigned long;
// GNU C 扩展了此处可以不使用等号直接赋值
static uint64 (*syscalls[])(void) = {
[SYS_fork] sys_fork, [SYS_exit] sys_exit, [SYS_wait] sys_wait, [SYS_pipe] sys_pipe,
[SYS_read] sys_read, [SYS_kill] sys_kill, [SYS_exec] sys_exec, [SYS_fstat] sys_fstat,
[SYS_chdir] sys_chdir, [SYS_dup] sys_dup, [SYS_getpid] sys_getpid, [SYS_sbrk] sys_sbrk,
[SYS_sleep] sys_sleep, [SYS_uptime] sys_uptime, [SYS_open] sys_open, [SYS_write] sys_write,
[SYS_mknod] sys_mknod, [SYS_unlink] sys_unlink, [SYS_link] sys_link, [SYS_mkdir] sys_mkdir,
[SYS_close] sys_close,
};
<if-section> ::= <if-group>
| <elif-group>
| <else-group>
| <endif-line>
考虑到宏与定义穿插, 这里直接将原始的文法(如下)打散: <if-section> ::= <if-group> <elif-group>* <else-group>? <endif-line>
<block-item> ::= <declaration>
| <statement>
| "..."
<struct-declaration> ::= <specifier-qualifier-list> <struct-declarator-list>? ";"
| <static_assert-declaration>
| "..."
if (x) {
...
}
struct free_area {
...
struct list_head free_list[MIGRATE_TYPES];
unsigned long nr_free;
};