How can I find the index of the first "item" in my string using Java?

I am working on writing a simple prologue interpreter in Java.

How can I find the last character index of the first element of either the head element or the tail element of the string in List Syntax?

The list syntax looks like this:

(X)
(pab)
(func (func2 a) (func3 XY))
(equal ean (mother cain))

The head for each of these lines is in order:
Leader: "X", index: 1
Leader: "p", index: 1
Leader: "func", Index: 4
Chapter: "equal", index: 5

Basically, I need to match the string that immediately follows the first "(" and ends with either a space or a closing ")", whichever comes first. I want the character index of the last character of the head element.

How can I match and get this index in Java?


Brabster's solution is really close. However, consider the case:
((b X) Y)

If the element is head (bx). I tried to fix this by removing the "(" from the delimiters of the scanner, but it still hiccups because of the space between "b" and "x".

Similarly: (((b W) X) Y) Z)

If the head is (((bw) x) Y).

+2


source to share


3 answers


The Java Scanner class (introduced in Java 1.5) might be a good start.

Here is an example that I think does what you want (updated to include the ability to count char)

public class Test {

    public static void main(String[] args) {

        String[] data = new String[] {
                "(X)",
                "(p a b)",
                "(func (func2 a) (func3 X Y))",
                "(equal eve (mother cain))",
                "((b X) Y)",
                "((((b W) X) Y) Z)"
        };


        for (String line:data) {
            int headIdx = 0;
            if (line.charAt(1) == '(') {
                headIdx = countBrackets(line);
            } else {
                String head = "";
                Scanner s = new Scanner(line);
                s.useDelimiter("[)|(| ]");
                head = s.next();
                headIdx = line.indexOf(head) + head.length() - 1;
            }
            System.out.println(headIdx);
        }

    }

    private static int countBrackets(String line) {
        int bracketCount = 0;
        int charCount = 0;
        for (int i = 1; i < line.length(); i++) {
            char c = line.charAt(i);
            if (c == '(') {
                bracketCount++;
            } else if (c == ')') {
                bracketCount--;
            }
            if (bracketCount == 0) {
                return charCount + 1;
            }
            charCount++;
        }
        throw new IllegalStateException("Brackets not nested properly");
    }
}

      



Output:

1
1
4
5
5
13

      

This is not a very neat solution, but regular expressions cannot be read (like parentheses). I would consider using a parser generator if there is another complication in there :)

+4


source


Is there a reason why you can't just reinstall it? Something like that?

public int firstIndex( String exp ) {
    int parenCount = 0;
    for (int i = 1; i < exp.length(); i++) {
        if (exp.charAt(i) == '(') {
            parenCount++;
        }
        else if (exp.charAt(i) == ')') {
            parenCount--;
        }
        if (parenCount == 0 && (exp.charAt(i+1) == ' ' || exp.charAt(i) == ')')) {
            return i;
        }
    }
}

      



I may be missing something, but I think it will work.

+1


source


I suggest you write the correct parser ( operator precedence in the case of Prolog) and represent the terms as Java object trees for further processing.

0


source







All Articles