1

I'm trying to make some sort of system that would detect java syntax and highlight that code. However, I seem to be having trouble finding a string within a string.

This is what I have so far:

import java.util.Scanner;

public class Client {

    private static String[] javaKeywords = {
        "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue",
        "default", "do", "double", "else", "enum", "extends", "final", "finnaly", "float", "for", "goto", "if",
        "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "package", "primitve",
        "private", "protected", "public", "return", "short", "static", "strictfp", "super", "switch", "synchronized", 
        "this", "throw", "throws", "transient", "try", "void", "volatile", "while"
    };

    private static String[] javaSyntax = {
        "++", "--", "~", "!", "*", "/", "%", "+", "-", " <<", ">>", ">>>", "<", ">", "<=", ">=", "==", "!=", "&",
        "^", "|", "&&", "||", "?", ":", "=", "+=", "-=", "/=", "%=", "&=", "^=", "|=", "<<=", ">>=", ">>>="
    };

    private static Scanner scanner = new Scanner(System.in);
    private static StringBuilder builder = new StringBuilder();

    public static void main(String args[]) {

        String input;

        while(!(input = scanner.nextLine()).toLowerCase().contains("exit")) {

            switch(input.toLowerCase()) {
                case "print":
                    System.out.println(builder.toString());
                    continue;

                case "clear":
                    builder = new StringBuilder();
                    continue;
            }

            builder.append(input + "\n");
            codeWrap(builder.toString());

        }

   }

    private static void codeWrap(String code) {
        int A4I = 0, position; // A4I = Account for insert length
        for(String keyword: javaKeywords) {

            if((position = findInString(code, keyword)) != -1) {
                builder.insert(position + A4I, "[code]");
                A4I += 6;
                builder.insert(position + keyword.length() + A4I, "[/code]");
                A4I += 7;
           }

        }
    }

    private static int findInString(String string, String keyword) {
        for(int index = 0, keywordIndex = 0; index < string.length(); index++) {

            keywordIndex = (string.charAt(index) == keyword.charAt(keywordIndex)) ? ++keywordIndex : 0;

            if(keywordIndex == keyword.length()) return ((index + 1) - keyword.length());

        }
        return -1;
    }

}

This works for the most part, however if you try to wrap a sentence with two keywords, if keyword b is before keyword a in the javaKeywords array it will return a strange result.

For example: result with a(abstract) before b(while)

abstract while
print
[code]abstract[/code] [code]while[/code]

result with b(while) before a(abstract)

while abstract
print
while [code]a[code]bstra[/code]ct[/code]
2
  • 1
    May I suggest using yacc and flex to check if a text is Java code (or at least resembles one)? Commented Jan 15, 2014 at 17:26
  • Thanks! This looks like something I might end up using. Commented Jan 15, 2014 at 17:34

1 Answer 1

1

Your A4I variable is not needed in this case and is causing you to make offsets that are already calculated. Observe the following:

while abstract
>loop finds 'abstract' at position 6
while [code]abstract[/code]
>A4I is now making all offsets +13
>loop finds 'while' found at position 0
>you add that +13 offset to the insert making it drop right in the middle of the abstract

You are also passing in 2 strings to your codeWrap method, because Strings are imutatable you are searching for an index in a string then using it on a different string. There are some other weird issues you will surly find in your program but this should fix your immediate one

private static void codeWrap() {
    int position;
    for(String keyword: javaKeywords) {

        if((position = findInString(builder.toString(), keyword)) != -1) {
            builder.insert(position, "[code]");
            builder.insert(position + keyword.length()+6, "[/code]");
       }

    }
}
2
  • Ah, Thank you! I was going around in circles trying to figure out what was wrong. Commented Jan 15, 2014 at 17:52
  • Remember, if your having problems just put some printlns out to debug your program. I just copied your 2 methods put a 2 line debug code in your main method : builder.append("abstract while"); codeWrap();. Also if the question is solved please mark as accepted answer :) Commented Jan 15, 2014 at 17:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.