001: /*
002: * Sun Public License Notice
003: *
004: * The contents of this file are subject to the Sun Public License
005: * Version 1.0 (the "License"). You may not use this file except in
006: * compliance with the License. A copy of the License is available at
007: * http://www.sun.com/
008: *
009: * The Original Code is NetBeans. The Initial Developer of the Original
010: * Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun
011: * Microsystems, Inc. All Rights Reserved.
012: */
013:
014: package org.netbeans.editor;
015:
016: import java.io.IOException;
017:
018: /**
019: * Debugging stuff for the syntax scanners
020: *
021: * @author Miloslav Metelka
022: * @version 1.00
023: */
024:
025: public class SyntaxDebug {
026:
027: public static final String NO_STATE_ASSIGNED = "NO STATE ASSIGNED"; // NOI18N
028: public static final String NULL_STATE = "NULL STATE"; // NOI18N
029: public static final String NULL_SYNTAX_MARK = "NULL SYNTAX MARK"; // NOI18N
030:
031: public Syntax syntax;
032:
033: public SyntaxDebug(Syntax syntax) {
034: this .syntax = syntax;
035: }
036:
037: /**
038: * Scans the whole file by some syntax scanner.
039: *
040: * @return number of tokens found
041: */
042: public int parseFile(String fileName) throws IOException {
043: char chars[] = Analyzer.loadFile(fileName); // line separator only '\n'
044: syntax.load(null, chars, 0, chars.length, true, 0);
045: int tokenCnt = debugScan();
046: return tokenCnt;
047: }
048:
049: /**
050: * Debug scanning on the given string. Write output to console. It returns
051: * number of tokens found (excluding EOL and EOT).
052: */
053: public int debugScan() {
054: int tokenCnt = 0;
055: while (true) {
056: TokenID tokenID = syntax.nextToken();
057: if (tokenID == null) { // end of buffer
058: System.out.println("EOT at offset="
059: + syntax.getTokenOffset());
060: return tokenCnt;
061: } else { // regular token
062: tokenCnt++;
063: System.out.println(tokenID.getName() // NOI18N
064: + " in "
065: + syntax.getTokenContextPath()
066: + ": TEXT='"
067: + EditorDebug.debugChars(syntax.getBuffer(), // NOI18N
068: syntax.getTokenOffset(), syntax
069: .getTokenLength())
070: + "', offset=" + syntax.getTokenOffset() // NOI18N
071: + ", len=" + syntax.getTokenLength() // NOI18N
072: );
073: }
074: }
075: }
076:
077: /**
078: * Tests if the scanning returns the same number of EOLs as there's actually
079: * '\n' characters in the whole buffer. The test is performed on the whole
080: * buffer.
081: */
082: /*
083: * public boolean eolTest(char chars[]) { int lfCount =
084: * Analyzer.getLFCount(chars); syntax.load(null, chars, 0, chars.length,
085: * true, 0); int eolCnt = 0; TokenID tokenID; do { tokenID =
086: * syntax.nextToken(); if (tokenID == Syntax.EOL) { eolCnt++; } } while
087: * (tokenID != Syntax.EOT); if (lfCount == eolCnt) { // test succeeded
088: * System.out.println("Test SUCCEEDED. " + lfCount + " new-lines found."); //
089: * NOI18N } else { System.out.println("Test FAILED! Number of '\\n' chars: " +
090: * lfCount // NOI18N + ", number of EOLs: " + eolCnt); // NOI18N } return
091: * lfCount == eolCnt; }
092: *
093: * /** Create array of arrays of chars containing wrong characters
094: */
095: /*
096: * protected abstract char[][] createWrongCharsArray();
097: * /* Some arrays of typical wrong characters that can appear in the
098: * tokens.
099: */
100: /*
101: * public static final char[] WRONG_NL = new char[] { '\n' }; public static
102: * final char[] WRONG_NL_TAB = new char[] { '\n', '\t' }; public static
103: * final char[] WRONG_NL_TAB_SPC = new char[] { '\n', '\t', ' ' };
104: *
105: * /** Wrong character arrays for the tokens
106: */
107: /*
108: * protected char[][] wrongCharsArray;
109: *
110: * public boolean checkTokenText(int tokenID) { boolean ok = true; if
111: * (wrongCharsArray == null) { wrongCharsArray = createWrongCharsArray(); }
112: * if (wrongCharsArray != null) { if (tokenID >= wrongCharsArray.length) {
113: * return false; } char[] wrongChars = wrongCharsArray[tokenID]; for (int i =
114: * curInd - tokenLength; i < curInd; i++) { for (int j = 0; j <
115: * wrongChars.length; j++) { if (buffer[i] == wrongChars[j]) {
116: * System.err.println("Token '" + getTokenName(tokenID) + "' having text " //
117: * NOI18N + debugTokenArea() + " contains wrong character '" // NOI18N +
118: * debugChars(wrongChars, j, 1) + "'. State: " + this); // NOI18N ok =
119: * false; } } } } return ok; }
120: *
121: * public String toStringArea() { return toString() + ", scan area=" +
122: * debugBufferArea(); // NOI18N }
123: *
124: * public String debugChars(char chars[], int offset, int len) { if (len <
125: * 0) { return "debugChars() ERROR: len=" + len + " < 0"; // NOI18N }
126: * StringBuffer sb = new StringBuffer(len); int endOffset = offset + len;
127: * for (; offset < endOffset; offset++) { switch (chars[offset]) { case
128: * '\n': sb.append("\\n"); // NOI18N break; case '\t': sb.append("\\t"); //
129: * NOI18N break; case '\r': sb.append("\\r"); // NOI18N break; default:
130: * sb.append(chars[offset]); } } return sb.toString(); }
131: *
132: *
133: * /** Return string describing the area between begInd and curInd
134: */
135: /*
136: * public String debugTokenArea() { return debugBufferArea(0, 0); }
137: *
138: * public String debugBufferArea() { return debugBufferArea(5, 5); }
139: *
140: * public String debugBufferArea(int preCnt, int postCnt) { StringBuffer sb =
141: * new StringBuffer(); int preStart = Math.max(begInd - preCnt, 0); preCnt =
142: * begInd - preStart; if (preCnt > 0) { sb.append(" prefix='"); // NOI18N
143: * sb.append(debugChars(buffer, preStart, preCnt)); sb.append("' "); //
144: * NOI18N } sb.append("'"); // NOI18N sb.append(debugChars(buffer, begInd,
145: * curInd - begInd)); sb.append("'"); // NOI18N postCnt = stopInd - curInd;
146: * if (postCnt > 0) { sb.append(" suffix='"); // NOI18N
147: * sb.append(debugChars(buffer, preStart, preCnt)); sb.append("' "); //
148: * NOI18N } return sb.toString(); }
149: *
150: */
151:
152: }
|