/*コメント*/を取り除く
Posted feedbacks - Other
#5239 をほぼそのままMac OS X (PowerPC 32bit) アセンブリで書き直したものです。
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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | .machine ppc
.globl _remove_comment_asm
INT8_MAX = 127
INT16_MAX = 32767
BEGIN_COMMENT = 12074 ; ('/'<<8)+'*'
END_COMMENT = 10799 ; ('*'<<8)+'/'
;; char *remove_comment_asm(char *s);
;;
;; r3: char *s
;; r4: char *retval
;; r5: char *buf
;; r6: int in_comment
;; r7: uint32_t next_match
;; r8: uint32_t cs
;;
;; r9: char c (*s)
;; r10: 8
;; r11: 16
_remove_comment_asm:
mr r4, r3 ; retval = s;
mr r5, r3 ; buf = s;
li r6, 0 ; in_comment = 0;
li r7, BEGIN_COMMENT ; next_match = BEGIN_COMMENT;
li r8, 0 ; cs = 0;
li r10, 8
li r11, 16
_scan:
lbz r9, 0(r3) ; (c = *s)
cmpli cr7, r9, 0 ; while (*s != 0) {
beq cr7, _scan_end
slw r8, r8, r10 ; cs <<= 8;
or r8, r8, r9 ; cs |= *s;
addi r3, r3, 1 ; s++;
;; if ((cs & INT16_MAX) == next_match) -> _match
andi. r12, r8, INT16_MAX
cmpl cr7, r7, r12
beq cr7, _match
;; else if (!in_comment && cs >= (1<<16)) { ...
cmpli cr7, r6, 0 ; !in_comment
lis r12, 1 ; (1<<16)
cmpl cr6, r8, r12 ; cs >= (1<<16)
cror 26, 25, 26 ; cr6[eq] = cr6[gt] || cr6[eq]
crand 2, 30, 26 ; cr0[eq] = cr7[eq] && cr6[eq]
bne cr0, _scan
lis r12, INT8_MAX ; INT8_MAX<<16
and r12, r8, r12 ; cs & (INT8_MAX<<16)
srwi r12, r12, 16 ; c = (cs & (INT8_MAX<<16)) >> 16;
stb r12, 0(r5) ; *buf = c;
addi r5, r5, 1 ; buf++;
b _scan
_match:
xori r6, r6, 1 ; in_comment = !in_comment;
cmpli cr7, r6, 1 ; in_comment ? ...
bne cr7, _set_begin_comment
li r7, END_COMMENT ; next_match = END_COMMENT;
b _write_before_comment
_set_begin_comment:
li r7, BEGIN_COMMENT ; next_match = END_COMMENT;
_write_before_comment:
mr r13, r8 ; r13 = cs
li r8, 0 ; cs = 0
cmpli cr7, r6, 1 ; if (in_comment) ...
bne cr7, _scan
lis r12, INT8_MAX ; INT8_MAX<<16
and r13, r13, r12 ; c = cs & (INT8_MAX<<16)
srw r13, r13, r11 ; c >> 16
stb r13, 0(r5) ; *buf = c;
addi r5, r5, 1 ; buf++;
b _scan
_scan_end:
cmpli cr7, r6, 1 ; if (!in_comment) ...
beq cr7, _func_return
cmpli cr7, r8, 256 ; if (cs >= 256) ...
blt cr7, _write_last_byte
li r12, INT8_MAX
slw r12, r12, r10 ; INT8_MAX<<8
and r13, r8, r12 ; c = cs & (INT8_MAX<<8)
srw r13, r13, r10 ; c >> 8
stb r13, 0(r5) ; *buf = c;
addi r5, r5, 1 ; buf++;
_write_last_byte:
andi. r9, r8, INT8_MAX ; cs & INT8_MAX
stb r9, 0(r5) ; *buf = c;
addi r5, r5, 1 ; buf++;
_func_return:
li r0, 0
stb r0, 0(r5) ; *buf = 0;
mr r3, r4 ; return retval;
blr
|


にしお
#3373()
Rating0/0=0.00
なお、「/*」と入力末尾で挟まれた部分も取り除いてください。 つまり、入力が「AAA/*BBB」なら出力は「AAA」です。 また、コメントは入れ子になりません。入力が「AAA/*BBB/*CCC*/DDD*/EEE」のとき、ひとつめの「*/」でコメントが終わるので出力は「AAADDD*/EEE」になります。 「//」や「**」が混ざる場合の挙動は失敗しやすいので要注意です。
Pythonでの実行例は下のようになります:
>>> remove_comment('AAA') 'AAA' >>> remove_comment('AAA/*BBB*/') 'AAA' >>> remove_comment('AAA/*BBB') 'AAA' >>> remove_comment('AAA/*BBB*/CCC') 'AAACCC' >>> remove_comment('AAA/*BBB/*CCC*/DDD*/EEE') 'AAADDD*/EEE' >>> remove_comment('AAA/a//*BB*B**/CCC') 'AAA/a/CCC'このお題は匿名での投稿を参考にして作成しました。 ありがとうございます。
[ reply ]