1 8 13 package jfun.parsec; 14 15 import jfun.util.IntArray; 16 17 18 29 public class DefaultPositionMap implements PositionMap, java.io.Serializable { 30 private final CharSequence src; 31 private final int start_lno; 32 private final IntArray line_breaks = new IntArray(20); 33 private int next_ind = 0; 34 private int next_col; 35 private final char line_break; 36 37 private int searchLineIndex(final int ind){ 38 final int len = line_breaks.size(); 39 int begin = 0; 40 int to = len; 41 for(;;){ 42 if(begin==to) return begin; 43 final int i = (to+begin)/2; 44 final int x = line_breaks.get(i); 45 if(x==ind) return i; 46 else if(x > ind){ 47 to = i; 48 } 49 else{ 50 begin = i+1; 51 } 52 } 53 } 54 private Pos searchPosition(final int ind){ 55 final int sz = line_breaks.size(); 56 if(sz==0){ 57 return newPos(0, ind+1); 58 } 59 else{ 60 final int last_break = line_breaks.get(sz-1); 61 if(ind > last_break){ 62 return newPos(sz, ind-last_break); 63 } 64 else{ 65 final int lno = searchLineIndex(ind); 66 if(lno==0){ 67 return newPos(0, ind+1); 68 } 69 else{ 70 final int previous_break = line_breaks.get(lno-1); 71 return newPos(lno, ind-previous_break); 72 } 73 } 74 } 75 } 76 private Pos searchForward(int ind){ 77 boolean eof = false; 78 if(ind==src.length()){ 79 eof= true; 80 ind--; 81 } 82 int col = next_col; 83 for(int i=next_ind; i<=ind; i++){ 84 final char c = src.charAt(i); 85 if(c == line_break){ 86 line_breaks.add(i); 87 col = 1; 88 } 89 else{ 90 col++; 91 } 92 } 93 this.next_ind = ind; 94 this.next_col = col; 95 final int lines = line_breaks.size(); 96 if(eof){ 97 return newPos(lines, col); 98 } 99 else if(col==1){ 100 return getLineBreakPos(lines-1); 101 } 102 else{ 103 return newPos(lines, col-1); 104 } 105 } 106 private int getLineBreakColumn(int lno){ 107 final int line_break = line_breaks.get(lno); 108 if(lno==0) 109 return line_break+1; 110 else{ 111 return line_break - line_breaks.get(lno-1); 112 } 113 } 114 private Pos getLineBreakPos(int lno){ 115 return newPos(lno, getLineBreakColumn(lno)); 116 } 117 private Pos newPos(int l, int c){ 118 return new Pos(start_lno+l, c); 119 } 120 124 public Pos getPos(final int n) { 125 if(n < next_ind){ 127 return searchPosition(n); 128 } 129 else{ 130 return searchForward(n); 131 } 132 } 133 152 159 public DefaultPositionMap(final CharSequence src, 160 final int lno, final int cno, final char line_break) { 161 this.src = src; 162 this.start_lno = lno; 163 this.next_col = cno; 164 this.line_break = line_break; 165 } 166 172 public DefaultPositionMap(final CharSequence src, 173 final int lno, final int cno) { 174 this(src, lno, cno, '\n'); 175 } 176 177 } 178 | Popular Tags |