View Javadoc
1 /* 2 * $Header: /cvsroot/plb4jedit/plb4jedit/Plb/src/java/net/sf/plb4jedit/plb/SourceLine.java,v 1.1 2003/11/04 17:40:31 skopp Exp $ 3 * 4 * Copyright 2001 Riege Software International, All Rights Reserved. 5 * 6 * This software is the proprietary information of Riege Software International 7 * Use is subject to license terms. 8 * 9 */ 10 package net.sf.plb4jedit.plb; 11 12 import java.util.Comparator; 13 import java.util.Iterator; 14 import java.util.List; 15 import java.util.regex.Matcher; 16 import java.util.regex.Pattern; 17 18 import org.gjt.sp.util.Log; 19 20 /*** 21 * Description: Represents a PLB-Source line, which is no comment.<br/> 22 * Parses a line from a source and determines wether it is a label, a variable, an include or a command. 23 * Gives access to these information and has some convenience methods to ask for the type of the line. 24 * <br/> 25 * 26 * Also defines some Comparators to sort SourceLines according to there lineno or in alphabetic order of their 27 * labels. 28 * <br/> 29 * 30 * A source line is scanned via a regular expression, which uses the structure/format of the PLB instruction syntax, 31 * which defines an instruction as something like 32 * <code> 33 * (LABEL) (KEYWORD) (REST) 34 * </code> 35 * where LABEL is of fix width (8 characters at RSI). Depending on the Type of the instruction LABEL can 36 * be the name of an instruction label or lroutine or a variable name. <br/> 37 * KEYWORD can be the type of a variable or a PLB command/keyword. 38 * <br/> 39 * Depending on the Type of the line, the REST can be a comment, name of an include, parameters to an lroutine. 40 * size of a variable, etc ... Be aware that for lines of Type INCLUDE only the first word of REST is taken where 41 * for other Types REST may need further parsing, because it can also contain comments or anything else. 42 * 43 * <br/> 44 * Notice that only a single Line is parsed, so e.g. for a routine which parameters a splitted over more than one 45 * line, not all parameter may be recognized. TODO: normalize PLB-Sources so that all line splits (by :) are 46 * resolved. 47 * <br/> 48 * @author Peter Schaefer 49 * @version $Header: /cvsroot/plb4jedit/plb4jedit/Plb/src/java/net/sf/plb4jedit/plb/SourceLine.java,v 1.1 2003/11/04 17:40:31 skopp Exp $ 50 */ 51 52 public class SourceLine { 53 final public static String cvsId = 54 "$Header: /cvsroot/plb4jedit/plb4jedit/Plb/src/java/net/sf/plb4jedit/plb/SourceLine.java,v 1.1 2003/11/04 17:40:31 skopp Exp $"; 55 56 private String line; 57 private Type type; 58 private int lineNumber; 59 private String label; 60 private String keyword; 61 private String rest; 62 private boolean isLabel; 63 64 /*** maximal possible width of a plb label, TODO: define via jEdit-Property, Plugin Option pane */ 65 private static String LABEL_WIDTH = "8"; 66 /*** 67 * regular expression used to split a line intot a LABEL (group 0), a KEYWORD (group 1) and the Rest up to 68 * the end of the line 69 */ 70 private static final Pattern SYNTAX = 71 Pattern.compile( 72 "(^[ a-zA-Z#$_0-9]{1,"+LABEL_WIDTH+"})//s*([a-zA-Z\".0-9]{0,10})//s*(.*)$"); 73 74 private static final Pattern RECORDLIKE = 75 Pattern.compile( 76 "^//s*like//s*([a-zA-Z#$_0-9]{1,"+LABEL_WIDTH+"}).*$"); 77 78 private static final Pattern RECORDARRAYLIKE = 79 Pattern.compile( 80 "^//s*//(//d//)//s*like//s*([a-zA-Z#$_0-9]{1,"+LABEL_WIDTH+"}).*$"); 81 /*** 82 * Constructs a SourceLine for a given line and it position of occurence in a file 83 * being nested inside record definitions. 84 * @param line one line of a Source file 85 * @param lineNumber where the line appears in the source file. 86 * @param records a list of records where this line is nested in 87 */ 88 public SourceLine(String line, int lineNumber, List records) { 89 this(line,lineNumber); 90 StringBuffer recordPrefix = new StringBuffer(); 91 Iterator it = records.iterator(); 92 while (it.hasNext()) { 93 recordPrefix.append(it.next().toString()); 94 recordPrefix.append("."); 95 } 96 label = recordPrefix.toString() + label; 97 } 98 99 /*** 100 * Constructs a SourceLine for a given line and it position of occurence in a file. 101 * @param line one line of a Source file 102 * @param lineNumber where the line appears in the source file. 103 */ 104 public SourceLine(String line, int lineNumber) { 105 this.isLabel = false; 106 this.line = line; 107 this.lineNumber = lineNumber; 108 this.label = ""; 109 this.keyword = ""; 110 this.rest = ""; 111 if (line.startsWith(".")) { 112 type = Type.COMMENT; 113 } else if (line.trim().length() == 0) { 114 type = Type.EMPTY; 115 } else { // can be VARDEF, ROUTINE, COMMAND, INCLUDE 116 Matcher aMatcher = SYNTAX.matcher(line); 117 if (aMatcher.matches()) { 118 label = aMatcher.group(1).trim(); 119 keyword = aMatcher.group(2).trim(); 120 rest = aMatcher.group(3).trim(); 121 //String comment = "";//aMatcher.group(4).trim(); 122 if (keyword.equals("inc")) { 123 type = Type.INCLUDE; 124 rest = getFirstWord(rest); 125 if (label.length() > 0) { 126 isLabel = true; 127 } 128 } else if ( 129 keyword.equals("afile") 130 || keyword.equals("bfile") 131 || keyword.equals("comfile") 132 || keyword.equals("const") 133 || keyword.equals("dbfile") 134 || keyword.equals("define") 135 || keyword.equals("dim") 136 || keyword.equals("equ") 137 || keyword.equals("equate") 138 || keyword.equals("file") 139 || keyword.equals("filelist") 140 || keyword.equals("form") 141 || keyword.equals("ifile") 142 || keyword.equals("init") 143 || keyword.equals("integer") 144 || keyword.equals("list") 145 || keyword.equals("pfile") 146 || keyword.equals("plform") 147 || keyword.equals("record") 148 || keyword.equals("sndfile") 149 || keyword.equals("varlist") 150 ) { 151 type = Type.VARDEF; 152 } else if ( 153 keyword.equals("external") 154 || keyword.equals("lroutine") 155 || keyword.equals("macro") 156 ) { 157 type = Type.ROUTINE; 158 isLabel = true; 159 } else if (!( 160 keyword.equals("recordend") 161 || keyword.equals("listend") 162 || keyword.equals("mend") 163 )) { 164 type = Type.COMMAND; 165 if (label.length() > 0) { 166 isLabel = true; 167 } 168 } else { 169 type = Type.UNKNOWN; 170 } 171 } else { 172 Log.log( 173 Log.DEBUG, 174 this, 175 "SYNTAX pattern doesn't match " + lineNumber + ":" + line); 176 } 177 } 178 } 179 180 /*** 181 * helper to get the first word out of s. 182 * TODO: better recognition of more whitespaces ?!; only used to get proper include names 183 * out or rest at the moment 184 * @param s trimmed string, so that it doesn't start with whitespaces. 185 * @return 186 */ 187 private String getFirstWord(String s) { 188 if (s.indexOf(" ") >= 0) { 189 return s.substring(0, s.indexOf(" ")).trim(); 190 } else if (s.indexOf("\t") >= 0) { 191 return s.substring(0, s.indexOf(" ")).trim(); 192 } else { 193 return s; 194 } 195 } 196 197 /*** 198 * 199 * @return true if SourceLine defines a label 200 */ 201 public boolean isLabel() { 202 return isLabel; 203 } 204 205 /*** 206 * gets the label of the line, see class documentation. Depending on Type of the line 207 * this may be an execution label/lroutine or variable definition. 208 * @return the label of this line 209 */ 210 public String getLabel() { 211 return label; 212 } 213 214 /*** 215 * 216 * @return the whole line. 217 */ 218 public String getLine() { 219 return line; 220 } 221 222 /*** 223 * 224 * @return line number 225 */ 226 public int getLineNumber() { 227 return lineNumber; 228 } 229 230 /*** 231 * gets keyword of the line. Depending on the Type of the line this may be 232 * the variable type, or a PLB keyword (like e.g. inc, lroutine, move, ....) 233 * @return the KEYWORD of the line, see class documentation 234 */ 235 public String getKeyword() { 236 return keyword; 237 } 238 239 /*** 240 * gets rest of the line. Content depends on Type. See class documentation. 241 * @return rest of the line 242 */ 243 public String getRest() { 244 return rest; 245 } 246 247 /*** 248 * gets the Type of the line, which indicates if the line is a comment, a variable definition, 249 * an execution label or a command. 250 * @return type of the line. 251 */ 252 public Type getType() { 253 return type; 254 } 255 256 /*** 257 * 258 * @return true if the line defines a dim 259 */ 260 public boolean isDimDef() { 261 return ( 262 type == Type.VARDEF 263 && (keyword.equals("dim") || keyword.equals("init"))); 264 } 265 266 /*** 267 * 268 * @return true if the line defines a form. 269 */ 270 public boolean isFormDef() { 271 return (type == Type.VARDEF && keyword.equals("form")); 272 } 273 274 /*** 275 * 276 * NOTE: records defined via like and record arrays are currently not supported 277 * 278 * @return true if the line defines the beginning of a record definition. 279 */ 280 public boolean isRecordDef() { 281 return ( (type == Type.VARDEF) 282 && (keyword.equals("record")) 283 && (!RECORDLIKE.matcher(rest).matches()) 284 && (!RECORDARRAYLIKE.matcher(rest).matches()) 285 ); 286 } 287 288 /*** 289 * 290 * @return true if the line defines the end of a record definition. 291 */ 292 public boolean isRecordEnd() { 293 return (keyword.equals("recordend")); 294 } 295 296 /*** 297 * 298 * @return true if the line defines a lroutine. 299 */ 300 public boolean isLroutine() { 301 return (type == Type.ROUTINE); 302 } 303 304 /*** 305 * 306 * @return true if the line includes another file 307 */ 308 public boolean isInclude() { 309 return (type == Type.INCLUDE); 310 } 311 312 /*** 313 * 314 * @return true if the line defines a variable 315 */ 316 public boolean isVarDef() { 317 return (type == Type.VARDEF); 318 } 319 320 public String toString() { 321 if (isLabel()) { 322 return lineNumber 323 + " is a " 324 + type 325 + ":" 326 + label.toUpperCase() 327 + " " 328 + keyword 329 + " " 330 + rest; 331 } else { 332 return lineNumber 333 + " is a " 334 + type 335 + ":" 336 + " " 337 + " " 338 + keyword 339 + " " 340 + rest; 341 } 342 } 343 344 public int compareTo(Object obj) { 345 SourceLine aLine = (SourceLine) obj; 346 return aLine.getLineNumber() - this.getLineNumber(); 347 } 348 349 public static final Comparator LINE_NUMBER_ORDERED = new Comparator() { 350 public int compare(Object obj1, Object obj2) { 351 SourceLine aLine = (SourceLine) obj1; 352 SourceLine bLine = (SourceLine) obj2; 353 return aLine.getLineNumber() - bLine.getLineNumber(); 354 } 355 }; 356 357 public static final Comparator LABEL_ORDERED = new Comparator() { 358 public int compare(Object obj1, Object obj2) { 359 SourceLine aLine = (SourceLine) obj1; 360 SourceLine bLine = (SourceLine) obj2; 361 int res; 362 if ((res = aLine.getLabel().compareToIgnoreCase(bLine.getLabel())) 363 != 0) { 364 return res; 365 } 366 res = aLine.getLineNumber() - bLine.getLineNumber(); 367 return res; 368 } 369 }; 370 371 public static final Comparator REST_ORDERED = new Comparator() { 372 public int compare(Object obj1, Object obj2) { 373 SourceLine aLine = (SourceLine) obj1; 374 SourceLine bLine = (SourceLine) obj2; 375 int res; 376 if ((res = aLine.getRest().compareToIgnoreCase(bLine.getRest())) 377 != 0) { 378 return res; 379 } 380 res = aLine.getLineNumber() - bLine.getLineNumber(); 381 return res; 382 } 383 }; 384 }

This page was automatically generated by Maven