0%

risc-v语法高亮

由于最近在写 rcore 教程的时候,里面涉及 risc-v 的汇编代码段,但是 gitbook 上面的语法高亮插件却不支持。然后决定弃用 gitbook 上面的插件,转而考虑两个更早一点出现的网页语法高亮库 highlight.js 以及 prismjs。

调研下来的结果是:

  • highlight.js 上面有 mips 的高亮,这个和 risc-v 的语法是比较相近的,就是一些寄存器和指令有所不同;
  • prismjs 上面对于汇编的语法支持就很有限了,和 risc-v 都搭不上边。而且我感觉我也不太能看懂怎么自己加入一门新语言。但是其好处是上面的插件很多,比如括号匹配,模仿终端,还有 Diff Highlight 等都是很好用的功能。

花了一下午照着 risc-v 手册写了个基于 prismjs 的语法高亮器,只需把下面这段加到下载下来的 prism.js 中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
Prism.languages.riscv = {
'comment': /#.*\n/,

'general-registers' : {
pattern: /\b(?:x[1-2]?[0-9]|x30|x31|zero|ra|sp|gp|tp|fp|t[0-6]|s[0-9]|s1[0-1]|a[0-7]|pc)\b/,
alias: 'class-name'
},
's-mode-csrs' : {
pattern: /\bs(?:status|tvec|ip|ie|counteren|scratch|epc|cause|tval|atp|)\b/,
alias: 'class-name'
},

/* timer & monitor csrs are not included yet */
'm-mode-csrs' : {
pattern: /\bm(?:isa|vendorid|archid|hardid|status|tvec|ideleg|ip|ie|counteren|scratch|epc|cause|tval)\b/,
alias: 'class-name'
},



'rv32/64i-instructions': {
pattern: /\b(?:(addi?w?)|(slti?u?)|(?:and|or|xor)i?|(?:sll|srl|sra)i?w?|lui|auipc|subw?|jal|jalr|beq|bne|bltu?|bgeu?|s[bhwd]|(l[bhw]u?)|ld)\b/,
alias: 'keyword'
},
'csr-instructions': {
pattern: /\b(?:csrr?[rws]i?)\b/,
alias: 'keyword'
},
'pseudo-instructions': {
pattern: /\b(?:nop|li|la|mv|not|neg|negw|sext.w|seqz|snez|sltz|sgtz|f(?:mv|abs|neg).(?:s|d)|b(?:eq|ne|le|ge|lt)z|bgt|ble|bgtu|bleu|j|jr|ret)\b/,
alias: 'important'
},

'relocation-functions': {
pattern: /(?:%hi|%lo|%pcrel_hi|%pcrel_lo|%tprel_(?:hi|lo|add))/,
alias: 'important'
},

/* 'function': /function/, */

'number': /(?:0x[\da-f]+|0o[0-7]+|\d+)/,

'operator': /operator/,
'data-emitting-directives': {
pattern: /(?:.2byte|.4byte|.8byte|.half|.word|.dword|.byte|.dtpreldword|.dtprelword|.sleb128|.uleb128|.asciz|.string|.incbin|.zero)/,
alias: 'tag'
},
'alignment-directives': {
pattern: /(?:.align|.balign|.p2align)/,
alias: 'tag'
},
'symbol-directives': {
pattern: /(?:.globl|.local|.equ)/,
alias: 'tag'
},
'section-directives': {
pattern: /(?:.text|.data|.rodata|.bss|.comm|.common|.section)/,
alias: 'tag'
},
'miscellaneous-directives': {
pattern: /(?:.option|.macro|.endm|.file|.ident|.size|.type)/,
alias: 'tag'
},

'labels': {
pattern: /\S*:/,
alias: 'operator'
},
'last-literals': {
pattern: /\b\S*\b/,
alias: 'operator',
},
};

比较简单,也不支持全部的指令,不过试了一下已经能用了。

有时间把这个弄到 gitbook 上面去。