KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jfun > parsec > DefaultPositionMap


1 /*****************************************************************************
2  * Copyright (C) Zephyr Business Solutions Corp. All rights reserved. *
3  * ------------------------------------------------------------------------- *
4  * The software in this package is published under the terms of the BSD *
5  * style license a copy of which has been included with this distribution in *
6  * the LICENSE.txt file. *
7  *****************************************************************************/

8 /*
9  * Created on Dec 12, 2004
10  *
11  * Author Ben Yu
12  */

13 package jfun.parsec;
14
15 import jfun.util.IntArray;
16
17
18 /**
19  * This default implementation of PositionMap.
20  * <p>
21  * This class internally keeps a cache of the positions of
22  * all the line break characters scanned so far,
23  * therefore repeated position lookup can be done in amortized log(n) time.
24  * </p>
25  * @author Ben Yu
26  *
27  * Dec 12, 2004
28  */

29 public class DefaultPositionMap implements PositionMap, java.io.Serializable JavaDoc {
30   private final CharSequence JavaDoc 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   //private final int tabwidth;
121
/*
122    * @see jfun.parsec.scanner.PositionMap#getSourcePos(int)
123    */

124   public Pos getPos(final int n) {
125     //return getPos(n, src, start_lno, start_cno);
126
if(n < next_ind){
127       return searchPosition(n);
128     }
129     else{
130       return searchForward(n);
131     }
132   }
133   /*
134   static Pos getPos(int n,
135       final CharSequence src,
136       final int lno, final int cno){
137     int ln = lno;
138     int cn = cno;
139     for(int i=0; i<n; i++){
140       final char c = src.charAt(i);
141       switch(c){
142         case '\n' :
143           ln++;
144           cn = 1;
145           break;
146         default:
147           cn++;
148       }
149     }
150     return new Pos(ln, cn);
151   }*/

152   /**
153    * Create a DefaultPositionMap object.
154    * @param src the source.
155    * @param lno the starting line number.
156    * @param cno the starting column number.
157    * @param line_break the line break character.
158    */

159   public DefaultPositionMap(final CharSequence JavaDoc 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   /**
167    * Create a DefaultPositionMap object.
168    * @param src the source.
169    * @param lno the starting line number.
170    * @param cno the starting column number.
171    */

172   public DefaultPositionMap(final CharSequence JavaDoc src,
173       final int lno, final int cno) {
174     this(src, lno, cno, '\n');
175   }
176
177 }
178
Popular Tags