Parsing with Scanner findWithinHorizon issue - java

in a project I'm working right now, I need to parse escape sequences with the Scanner class (using Java in Linux). To include, for instance, the two END keys in the keyboard, I initially wrote the following code:
if(sc.findWithinHorizon("(\\G\\e\\[4~)?",0).length() > 0 || sc.findWithinHorizon("(\\G\\eOF)?",0).length() > 0 ) {
System.out.print("END"); //To see if it works
With that code, I don't get any output (the terminal just freezes). After seeing that, I separated the two condition in two different if's:
if(sc.findWithinHorizon("(\\G\\e\\[4~)?",0).length() > 0)
System.out.print("END");
else if(sc.findWithinHorizon("(\\G\\eOF)?",0).length() > 0 )
System.out.print("END");
Then it works. Does anybody know why it doesn't work with the OR operator?
Thanks in advance.

You'll want to capture what findwithinhorizon parses into a String then do your comparisons. What you're doing in the first if statement is parsing sc twice. Once doing a comparison for something then the second time doing a different comparison on a different part of the text.
I doubt this is the behavior you wanted. when you set horizon to 0 it's going to look at what is the current position then increment the position by one, so your second call is looking at a different index. If you truly have reached the end of the file I would believe this would cause some odd behavior and explain why it hangs.

Related

Using If-Statement as test condition for For-Loop in Vb.net

I've been writing some software in Vb.net and I've come to a point in the program where it would be best if I could place an if-statement in the header of a for-loop.
For example, in java, I could achieve what I need like so..
for (int I = 0; myArray[I].compareTo("") == 0; I ++)
{
'code here
}
Unfortunately in Vb.net, all I know how to do is increment one number to a given number in a for-loop. I am aware however, that what I need to do can be accomplished using an if-test inside the for-loop
For I as Integer = 0 To myArray.length 'only possible test is comparison between two ints
'code here
If myArray(I).compareTo("") <> 0 Then
Exit For
End If
Next
Its not a big deal having to do this but if there is a way to streamline this more into the for-loop control then I would like to know for now and future reference.
So my question is, is it possible to check an if-condition (other than comparing two numbers) inside the header of a for-loop in Vb.net?
Update: In response to #Olivier Jacot-Descombes 's answer, I just wanted to clarify that I know while loops are used to test if-conditions in loops, but they lose the functionality of auto-incrementing possessed by for-loops. In Java, for-loops can do both of these. Which is why I'm wondering if Vb.net has the same functionality all within the header of a for-loop control somehow.
Use a While-Loop instead
Dim i As Integer = 0
While i < myArray.Length AndAlso String.IsNullOrEmpty(myArray(i))
'Code here
i += 1
End While
In VB a string can be empty ("") or Nothing (null in C#). In order to cope with both situations use String.IsNullOrEmpty(s).
AndAlso (unlike And) ensures shortcut evaluation. I.e. if the first condition is not True then the second will not be evaluated. We need this here, otherwise the array would throw an "Index out of bounds" exception. Note also that the array index goes from 0 to array.Length - 1.
But you can also exit from a For-loop with Exit For
For I As Integer = 0 To myArray.Length-1
'code here
If Not String.IsNullOrEmpty(myArray(I)) Then
Exit For
End If
Next
But exiting a loop like this can make the code unreadable. The problem is that the For-loop has now 2 exit points and loop and exit conditions defined at different places.
There is also a Do...Loop statement allowing you to test the condition at the end of the loop.
The short answer is no. Visual Basic languages don't have anything like the C/java style for() loop.
The longer answer is that depending on what you want, you might not even need a loop.
Dim a = {"a", Nothing, "", "b"}
' this will print from 0 to 1, but Array.IndexOf returns -1 if value is not found
For i = 0 To Array.IndexOf(a, "") - 1
Debug.Print(i & "")
Next
For Each item In a : If item = "" Then Exit For ' this is actually 2 lines separated by :
Debug.Print("'{0}'", item)
Next
For Each item In a.TakeWhile(Function(s) s > "") ' TakeWhile is a System.Linq extension
Debug.Print("'{0}'", item)
Next
a.TakeWhile(Function(s) s > "").ToList.ForEach(AddressOf Debug.Print) ' prints a
a.TakeWhile(Function(s) s > "").ToList.ForEach(Sub(s) Debug.Print(s)) ' prints a

How to prvent Xtend templates from printing Variables during loop

I am using the Xtend templates to write a small program. I try using the IF statement, but every time I execute it it prints the variable in the console, which I dont want it to.
«IF x==y»
The jump value is «database.get(2)»
«jump_var_letter = String.charAt(1)»
«old_jump_ahd=database.get(2) »
«ENDIF»
Here the database is an array of integers and String is an array of letters. Here I just want it to print the value found at database.get(2) i.e 5. The last two expressions befor the ENDIF is meant for assignning a few values( which need not be printed)
The jump value is 5
Instead I get
The jump value is 5
D
5
Could somebody please tell me how I could stop printing the other two values.
Thank you in advance for your help..
After looking for sometime on the net I found that you could prevent the printing of the expreesions in between by using block expressions and then returning a null expression. (Although this method is not encouraged, I found that it provides me the result I wanted). So the expression I posted could be written as:
«IF x==y»
The jump value is «database.get(2)»
«{jump_var_letter = String.charAt(1); "" }»
«{old_jump_ahd=database.get(2); ""} »
«ENDIF»
This prints
The jump value is 5.

Validating One of Two Choices

This is working for "draw" but not for discard". I just want it to validate whether the input is one of the two. I run into this problem frequently and don't understand why. Does anyone see the problem?
while(!(choice.equalsIgnoreCase("draw") && !(choice.equalsIgnoreCase("discard"))))
Thanks.
If you're trying to check if the input is one of the two, you want to do
while(choice.equalsIgnoreCase("draw") || choice.equalsIgnoreCase("discard"))
Right now you're only entering the loop when choice is neither "draw" nor "discard"
You forgot to close a parenthesis for the "draw" test, you could use
while (!(choice.equalsIgnoreCase("draw")) &&
!(choice.equalsIgnoreCase("discard")))
or
while (!choice.equalsIgnoreCase("draw") &&
!choice.equalsIgnoreCase("discard"))
or use De Morgan's Laws like
while (!(choice.equalsIgnoreCase("draw") ||
choice.equalsIgnoreCase("discard")))
Simplify it (and watch your parentheses in the future):
while(choice.equalsIgnoreCase("draw") || choice.equalsIgnoreCase("discard")) {
// code
}
What your code is currently doing is this:
!(choice.equalsIgnoreCase("draw") && !(choice.equalsIgnoreCase("discard")))
Pay close attention to that negation. It's closing the entire expression, because you've opened up the paren too wide. That would evaluate to true only if you entered in "discard".
If you meant to say this:
!choice.equalsIgnoreCase("draw") && !choice.equalsIgnoreCase("discard"))
Then that contradicts what you're trying to evaluate - you want to check to see if one of those evaluates to true. If you correct the parentheses, then it would still be incorrect, as it only evaluates if both of those statements are false.

Java string split length

System.out.println("neon.mems.cmu.edu/people/".split("/").length); // output is 2
I was doing some url processing. To my surprise I just got the result above. I thought the number of elements could be the number of splitters plus one.
I didn't realize the last empty string(or just null) is cut off from the splitted array until now. I wonder if this is the case with every programming language.
No that's not the case for every programming language and there is no universal specification so there is no reason it should be.
Go
a := strings.Split("neon.mems.cmu.edu/people/", "/")
fmt.Println(len(a)) // prints 3
Javascript
Type this in the console of your browser :
"neon.mems.cmu.edu/people/".split('/')
The result is
["neon.mems.cmu.edu", "people", ""]
What you should do when a match is empty isn't something obvious or inherent to the split concept. A proof of that is that old Internet Explorer versions did remove those empty matches.
why it is discarded empty string?
String#split(regx) internally call String#split(regx,0) which execute Pattern.compile(regex).split(this, limit); actually - code snippet
if (limit == 0)
while (resultSize > 0 && matchList.get(resultSize-1).equals(""))
resultSize--;
where empty string has been discarded from resultSize if limit is 0.
How to get desired result?
String#split(regx,limit) use get desired result.
System.out.println("neon.mems.cmu.edu/people/".split("/",3).length);
Result :
3
And about language specification I am agree with #dystroy

Using the same class at 3 places concurrently

I'm currently working on a basic parser in Java and I have run into a problem when it comes to loops. Say I want to parse a while loop it would look something like:
a = 0
WHILE a < 10
a = a + 1
WEND
This example contains 4 expressions one of which will only need to be parsed ones the others will need to be parsed 10 times. The first one being the initial a = 0, second and third being on each side of the condition in the WHILE statement and the last one being within the WHILE block.
When I wrote the interpreted for this it loads the expression class into 4 different variables as new, the reevaluates them for each time it runs.
My problem is that even though they are initially loaded as new classes each time, there is over flow between them so when I re-parse them all of them looks like the last one:
a + 1
Any advice on how to circumvent this?
The code base is rather big so I wont post it here but its available at: http://git.life-hack.org/basic-parser/tree/src/parser
The file I'm working in is LoopBlock.java

Categories