/*
* Copyright 2012 Phil Pratt-Szeliga and other contributors
* http://chirrup.org/
*
* See the file LICENSE for copying permission.
*/
package org.trifort.rootbeer.deadmethods;
import java.util.ArrayList;
import java.util.List;
public class SegmentParser {
public static final int TYPE_FREE = 0;
public static final int TYPE_COMMENT = 1;
public static final int TYPE_STRING = 2;
public static final int TYPE_CHAR = 3;
public static final int TYPE_DEFINE = 4;
public SegmentParser(){
}
public List<Segment> parse(String contents) {
List<Segment> ret = new ArrayList<Segment>();
int state = TYPE_FREE;
StringBuilder accum = new StringBuilder();
for(int i = 0; i < contents.length(); ++i){
char c = contents.charAt(i);
char cc = '\0';
if(i < contents.length() - 1){
cc = contents.charAt(i+1);
}
switch(state){
case TYPE_FREE:
if(c == '/' && cc == '/'){
if(accum.length() != 0){
ret.add(new Segment(accum.toString(), TYPE_FREE));
}
accum = new StringBuilder("//");
state = TYPE_COMMENT;
++i;
} else if(c == '\"'){
if(accum.length() != 0){
ret.add(new Segment(accum.toString(), TYPE_FREE));
}
accum = new StringBuilder("\"");
state = TYPE_STRING;
} else if(c == '\''){
if(accum.length() != 0){
ret.add(new Segment(accum.toString(), TYPE_FREE));
}
accum = new StringBuilder("\'");
state = TYPE_CHAR;
} else if(c == '#' && onlyWhitespace(accum)){
if(accum.length() != 0){
ret.add(new Segment(accum.toString(), TYPE_FREE));
}
accum = new StringBuilder("#");
state = TYPE_DEFINE;
} else if(c == '}' || c == '{'){
accum.append(c);
ret.add(new Segment(accum.toString(), TYPE_FREE));
accum = new StringBuilder("");
} else if(c == '\n'){
if(accum.length() != 0){
ret.add(new Segment(accum.toString(), TYPE_FREE));
}
accum = new StringBuilder("");
} else {
accum.append(c);
}
break;
case TYPE_COMMENT:
if(c == '\n'){
if(insideEscape(contents, i - 1)){
accum.append(c);
} else {
if(accum.length() != 0){
ret.add(new Segment(accum.toString(), TYPE_COMMENT));
}
accum = new StringBuilder();
state = TYPE_FREE;
}
} else {
accum.append(c);
}
break;
case TYPE_STRING:
if(c == '\"'){
if(insideEscape(contents, i - 1)){
accum.append(c);
} else {
accum.append(c);
ret.add(new Segment(accum.toString(), TYPE_STRING));
accum = new StringBuilder();
state = TYPE_FREE;
}
} else {
accum.append(c);
}
break;
case TYPE_CHAR:
if(c == '\''){
if(insideEscape(contents, i - 1)){
accum.append(c);
} else {
accum.append(c);
ret.add(new Segment(accum.toString(), TYPE_CHAR));
accum = new StringBuilder();
state = TYPE_FREE;
}
} else {
accum.append(c);
}
break;
case TYPE_DEFINE:
if(c == '\n'){
if(insideEscape(contents, i - 1)){
accum.append(c);
} else {
if(accum.length() != 0){
ret.add(new Segment(accum.toString(), TYPE_DEFINE));
}
accum = new StringBuilder();
state = TYPE_FREE;
}
} else {
accum.append(c);
}
break;
}
}
if(accum.length() != 0){
ret.add(new Segment(accum.toString(), state));
}
return ret;
}
private boolean insideEscape(String contents, int index){
int count = 0;
for(int i = index; i >= 0; --i){
char c = contents.charAt(i);
if(c == '\\'){
++count;
} else {
break;
}
}
if(count % 2 == 0){
return false;
} else {
return true;
}
}
private boolean onlyWhitespace(StringBuilder builder){
for(int i = 0; i < builder.length(); ++i){
char c = builder.charAt(i);
if(c != ' ' && c != '\n'){
return false;
}
}
return true;
}
}