1 module ddparser.scan; 2 3 4 import ddparser.dparse; 5 import ddparser.parse; 6 import ddparser.dparse_tables; 7 import ddparser.util; 8 import std.stdio; 9 10 struct ShiftResult 11 { 12 SNode* snode; 13 const(D_Shift)* shift; 14 d_loc_t loc; 15 } 16 17 private void do_smth(State)(ref d_loc_t loc, ref d_loc_t last_loc, 18 ref int nresults, 19 ref D_Shift*[] shift, const ref D_State parse_state, ShiftResult[] results) 20 { 21 /* all matches */ 22 auto st = cast(SB_!(State)[])parse_state.scanner_table; 23 auto tst = cast(SB_trans!(State)[])parse_state.transition_table; 24 State state, last, prev; 25 26 const(char) *s = loc.s; 27 int col = loc.col, line = loc.line; 28 29 while (true) 30 { 31 uint8 c = cast(uint8)*s++; 32 uint32 sb = c >> SCANNER_BLOCK_SHIFT; 33 uint32 so = c & SCANNER_BLOCK_MASK; 34 state = st[state].scanner_block[sb][so]; 35 if (!state) break; 36 37 --state; 38 39 if (prev && parse_state.accepts_diff) { 40 const D_Shift*[] shift_diff = parse_state.accepts_diff[tst[prev].scanner_block[sb][so]]; 41 foreach(sd; shift_diff) { 42 results[nresults].loc = loc; 43 results[nresults++].shift = sd; 44 } 45 } 46 prev = state; 47 if (c == '\n') { line++; col = 0; } else col++; 48 loc.s = s; loc.line = line; loc.col = col; 49 if (st[state].shift) { 50 last = state; 51 last_loc = loc; 52 } 53 } 54 shift = st[last].shift; 55 } 56 57 int 58 scan_buffer(d_loc_t loc, const ref D_State parse_state, ShiftResult[] results) { 59 d_loc_t last_loc = loc; 60 int nresults = 0; 61 D_Shift *[]shift; 62 63 switch (parse_state.scanner_size) { 64 case 1: 65 do_smth!ubyte(loc, last_loc, nresults, shift, parse_state, results); 66 break; 67 case 2: 68 do_smth!ushort(loc, last_loc, nresults, shift, parse_state, results); 69 break; 70 case 4: 71 do_smth!uint(loc, last_loc, nresults, shift, parse_state, results); 72 break; 73 default: 74 } 75 76 foreach(s; shift) { 77 results[nresults].loc = last_loc; 78 results[nresults++].shift = s; 79 } 80 81 if (nresults) { 82 bool longest = parse_state.scan_kind == D_SCAN_LONGEST; 83 const char *end = results[nresults-1].loc.s; 84 85 int i = 0; 86 if (parse_state.scan_kind == D_SCAN_MIXED) { 87 for (i = nresults - 1; i >= 0; i--) { 88 if (results[i].loc.s < end) 89 break; 90 if (results[i].shift.shift_kind == D_SCAN_LONGEST) 91 longest = true; 92 } 93 } 94 95 if (longest) { 96 /* keep only 'longest' */ 97 i = 0; 98 for (int j = 0; j < nresults; j++) { 99 if (results[j].loc.s == end || results[j].shift.shift_kind == D_SCAN_TRAILING) { 100 if (i != j) 101 results[i] = results[j]; 102 i++; 103 } 104 } 105 nresults = i; 106 } else if (parse_state.scan_kind == D_SCAN_MIXED) { 107 /* only keep non-longest */ 108 for (int j = i; j >= 0; j--) 109 if (results[j].shift.shift_kind != D_SCAN_LONGEST) { 110 if (i != j) 111 results[i] = results[j]; 112 i--; 113 } 114 nresults = nresults - i - 1; 115 if (i != -1) 116 for (int j = 0; j < nresults; ++j) 117 results[j] = results[i + j + 1]; 118 } 119 } 120 return nresults; 121 } 122