I try to parse arguments by a recursive descent
schema.
The while
statements calls an eat!
function after every execution to get the next $current_token
to process.
The problem now is that this way it goes into an infinite loop.
To be exact, there are two while loops in the function.
Either one of them or both are not working because the compound is syntactically (or logically?) wrong.
Could you please check what might be wrong with the following code on the many levels possible?
1)
while $(isWord? $current_token) || ! $(isVersionNumber? $current_token) && ! $(endOfInput?); do
while isVersionNumber? $current_token && ! endOfInput?; do
Also what is correct? To put the checking-functions in a command substitution or not?
Could it be that short-circuiting also prevents the endOfInput?
-test ?
Because that should absolutely stop the loop.
On request of ilkkachu
The test functions' code:
isWord? () {
local pattern="^[a-zA-Z0-9_-]+$"
if [[ $1 =~ $pattern ]]; then
echo true
else
echo false
fi
}
isVersionNumber? () {
local pattern="^[0-9]{1,2}(.[0-9]{,2})*$"
if [[ $1 =~ $pattern ]]; then
echo true
else
echo false
fi
}
EO_ARGS=1
function endOfInput? {
if [ $current_token_index -ge $ARGC ]; then
EO_ARGS=0
fi
echo $EO_ARGS
}
I assume it outputs another command, since you're using it in a command substitution?
No it was just a try because I don't know whether or not I can just call the functions in the conditional without command substitution.
For completeness' sake, I also add the eat!
function.
eat! () {
if [[ ! $(($current_char_index + 1)) -gt $ARGC ]]; then
current_token=${ARGV[$current_token_index]}
((current_token_index += 1))
current_char=${current_token:0:1}
}
And may the conditions maybe be formulated better with test
/ [
([[
) ?
Could the exclamation mark be the point of failure?
The following seems to be syntactically wrong:
while [ endOfInput -eq 1 ] && isWord? "$current_token" || ! isVersionNumber? "$current_token"; do
From the bracket [
I get the error message
[: endOfInput: integral expression expected (translation)
?
and!
characters? That's brave – Chris Davies Jun 04 '21 at 13:17printf "X1\tX2\tX3\tResult\n"; for x1 in false true; do for x2 in false true; do for x3 in false true; do printf "%s\t%s\t%s\t" $x1 $x2 $x3; if $x1 || ! $x2 && ! $x3; then echo true; else echo false; fi; done; done; done
– Chris Davies Jun 04 '21 at 13:20while command && ! command; do : ...; done
(i.e. your #2) is correct syntax – Chris Davies Jun 04 '21 at 13:22isWord?
? You're not showing that part of the code. It's a command, right? Which does, what exactly? I assume it outputs another command, since you're using it in a command substitution? If you were to [edit] the question to remove all the unnecessary chatter, and focus on presenting what you're trying to do, it might be easier to give answers – ilkkachu Jun 04 '21 at 13:23eat!
function"? Is thateat!
function relevant? If not, you can leave this sort of statements out, they only work to distract. If the problem is with the loop conditions, stick to them. If the function is relevant, then you probably need to show that one too. "To be exact, there are two while loops in the function." -- also these? Which two while loops? – ilkkachu Jun 04 '21 at 13:35&&
and||
rather often.) Now we need to guess if that's the problem, or if you know that part already. And yes, I asked about command substitution, since you used it there, so I expected you'd know what it does. And what the difference is between$(foo)
andfoo
. – ilkkachu Jun 04 '21 at 13:39?
and!
in function names. – choroba Jun 04 '21 at 13:43&&
and||
correctly 3) and if the way I would do would be the way thatwhile
expects. Also, as I said, Then I don't know if other laws like short circuiting might prevent the testing ofendOfInput?
for example. – von spotz Jun 04 '21 at 13:44while command && ! command; do : ...; done
is ok, but when I have the&& ! endOfInput?
part added, the loop won't be entered, although the return value is false at that time. Edit: it also prevents the firstwhile
loop from being entered.while isWord? $current_token || ! isVersionNumber? $current_token && ! $(endOfInput?); do
Could it have to do with the&&
operator? – von spotz Jun 04 '21 at 13:52while isWord? $current_token || ! isVersionNumber? $current_token && ! $(endOfInput?)
towhile X1 || ! X2 && ! X3
. Now run the truth table code I gave you earlier and check if the three inputs give you the expected output – Chris Davies Jun 04 '21 at 14:12false
at the place ofX3
the loop is entered. So this seems to be a logical problem rather. I will investigate. – von spotz Jun 04 '21 at 14:23endOfInput?
is false so I don't understand the difference why it suddenly enters the loop when I just putfalse
in place of the function call. edit: renaming it such that it lacks the?
at the end also does nothing. – von spotz Jun 04 '21 at 14:28while isWord? "$current_token" || ( ! isVersionNumber? "$current_token" && ! endOfInput); do
then thewhile
loop is entered. Just don't know what to do with the secondwhile isVersionNumber? "$current_token" && ! endOfInput; do
– von spotz Jun 04 '21 at 14:51&&
and||
. If you're coming from a programming language such as Ruby it may not be what you expect – Chris Davies Jun 04 '21 at 15:52