[Clang RecursiveASTVisitor]How to make a distinction between 'If' statement and 'Else If' statement? - clang

I'm using clang's RecursiveASTVisitor to parse some C code. I override visitStmt() and want to make a distinction between 'If' statement and 'Else If' statement.
Example:
if(a > 0){
XXX
}
else if(a == 0){
YYY
}
else{
ZZZ
}
In visitStmt(), I use:
if(isa<IfStmt>(S))
to judge whether a statement is IfStmt.
But how can I know the statement is 'Else If' rather than 'If'?
I want to insert different stubs(XXX under 'If' and YYY under 'Else If').
ps: I'm not a native English speaker. Please forgive me for my poor express.

In C there is not specific else if statement, because
if (a) {
...
}
else if (b) {
...
}
else {
...
}
is conceputally (and in terms of an AST) something like the following
if (a) {
...
}
else {
if (b) {
...
}
else {
...
}
}
So the first snippet is sort of a "hidden nesting", because the body of the first else just consists of a single if ... else statement, so you can omit the {} around it. And the last else does not belong to the first if but to the second.
So what you probably can do to determine whether you have an else if or not, is step up in the tree, and check if the parent node of the current node is an else statement and the if is the first (or only) statement in that parent-else's body.
There are other languages (for instance VB) which have a If .. ElseIf .. Else construct. But C doesn't.

Related

Control Statement Violation inside for-loop

I am using SwiftLint in my app. I am getting Control Statement Violation: if, for, guard, switch, while, and catch statements shouldn't unnecessarily wrap their conditionals or arguments in parentheses. (control_statement).
What is wrong with that code? Why i am getting that waring?
Thanks in Advance
for i in 0..<images.count {
if(i == images.endIndex - 1) {
print(i)
}
}
Its simply telling parentheses start ( and parentheses end ) symbols are now not necessary to provide in control statement' conditions so your code will go without () in control statement conditions for example your code will look like below
for i in 0..<images.count {
if i == images.endIndex - 1 {
print(i)
}
}
You have added parentheses in if condition.
Remove it.
for i in 0..<images.count {
if i == images.endIndex - 1 {
print(i)
}
}
You can check detail rule here.

Is there a language where we can mark value as result and then continue function/method body?

I was reading smalltalk tutorial and this idea came to my mind.
Assume we have some language and there instead of return we're marking some value as final return value and then we continue method, once method end is reached - no matter what else was called we're returning marked value unless something else specified manually like this:
Let's say ^^ is a operator that marks value for return if no explicit return is found till end of method
m1()
{
^^1;
some_other_code;
}
m2(par)
{
^^2;
if par == 1: return 1;
some code;
}
m3(par)
{
if par == 1: return 1;
else if par == 0: ^^0;
do some stuff;
if par < 0: return -1;
}
m1() should return 1
m2(0) should return 2
m2(1) should return 1
m3(0) should return 0
m3(1) should return 1
m3(-2) should return -1
This is a little similar to ruby's tap() but not the same
Pascal did that. The return value was set by assigning to the function name. Swift does something not quite the same: You can mark code anywhere that will be executed when the function exits. Your return statement exists, but only after other code written somewhere else gets performed.

What is the difference between a return and a break in an infinite loop?

In doing the Guessing Game from the Rust Book (I won't put the link because it will probably not exist in a few weeks), there is a point where you use return to break out of the loop. I used break instead:
loop {
guess = guesser();
guess_cast = guess.trim().parse();
let guess_num = match guess_cast {
Ok(num) => num,
Err(_) => {
println!("Guess was not a number, try again");
continue;
},
};
if guess_num < answer {
println!("Too low");
} else if guess_num > answer {
println!("Too high");
} else {
println!("You guessed it!");
break;
}
}
Is there a real difference in using return over break in this case? What about other cases when you want to break out of an infinite loop?
If the loop is the final statement in the function, then there is patently no functional distinction between break; and return;. If this condition does not hold, there is evidently a difference, for return terminates execution of the function, while break only terminates execution of the loop.
In the case where they are functionally the same, which you use may vary based on context (which one feels better in this particular location), personal preference and what, if anything, you ate for breakfast.

Creating an app that defines a set of data based on several criteria

I'm trying to create an iPhone app that takes the user's response to four criteria and, based on that, shows a specific set of data related to that permutation of answers. For example, in the main view controller:
User selects A or B in a segmented controller (let's say they choose A)
User selects C or D in a segmented controller (they choose D)
User selects E or F in a segmented controller (they choose E)
User inputs an age in a text box (they type in 37)
User touches the "Get Numbers" button
Based on the combination of "A, D, E, 37", the view that appears on the touch of "Get Numbers" shows an image overlaid with seven labels containing the numbers 17.1, 14.2, 30.0, 60.4, 18.1, 19.7 and 80.2. If the user had selected a different set of responses on the main controller, a different set of numbers would appear in those same labels.
I've researched the various elements, but I can't figure out how to combine them to produce the desired outcome. How can I do this? Any advice would be much appreciated--I'm quite new to xCode and completely stuck.
Thanks
I do not actually program in Xcode or Objective-C, but it seems to me that you are looking for a CASE statement. I found the following links, I hope they help:
the best way to implement readable switch case with strings in objective-c?
http://www.techotopia.com/index.php/The_Objective-C_switch_Statement
Based on your question, this is all contained in one viewController so you shouldn't need to pass a bunch of properties. The hard part is knowing how you are attempting to mutate the values and how much branching needs to happen. Also, you have 7 return values and there's no way of knowing how to compute these, like if the output from the first response is calculated with the second and third responses, etc.
EDIT, after reading your comment:
There are 8 possible outcomes, maybe you can create 8 methods to deal with each one. I can't think of any other way, but correct me if I'm wrong:
Possible values:
{
(A,C,E) ;
(B,C,E) ;
(A,D,E) ;
(B,D,E) ;
(A,C,F) ;
(B,C,F) ;
(A,D,F) ;
(B,D,F) ;
}
//Do it with an IF statement:
//first capture state into BOOL values
BOOL a = NO;
BOOL c = NO;
BOOL e = NO;
if (abSegment.selectedSegmentIndex == 0) { a = YES; }
if (cdSegment.selectedSegmentIndex == 0) { c = YES; }
if (efSegment.selectedSegmentIndex == 0) { e = YES; }
//next do some matching with IF statements
if (a && c && e) {
//do something for A,C,E
}
if (!a && c && e) {
//do something for B,C,E
}
if (a && !c && e) {
//do something for A,D,E
}
if (!a && !c && e) {
//do something for B,D,E
}
if (a && c && !e) {
//do something for A,C,F
}
if (!a && c && !e) {
//do something for B,C,F
}
if (a && !c && !e) {
//do something for A,D,F
}
if (!a && !c && !e) {
//do something for B,D,F
}
If you have hardcoded values you can just write the label updating text inside each IF block that matches your requirements. It's hacky but it's all I can think of right now

ANTLR Tree Grammar for loops

I'm trying to implement a parser by directly reading a treeWalker and implementing the commands needed for the compiler on the fly. So if I have a command like:
statement
:
^('WRITE' expression)
{
//Here is the command that is created by my Tree Parser
ch.emitRO("OUT",0,0,0,"write out the value of ac");
//and then I handle it in my other classes
}
;
I want it to write OUT 0,0,0; to a file. That's my grammar.
I have a problem though with the loop section in my grammar it is:
'WHILE'^ expression 'DO' stat_seq 'ENDDO'
and in the tree parser:
doWhileStatement
:
^('WHILE' expression 'DO' stat_seq 'ENDDO')
;
What I want to do is directly parse the code from the while loop into the commands I need. I came up with this solution but it doesn't work:
doWhileStatement
:
^('WHILE' e=expression head='DO'
{
int loopHead =((CommonTree) head).getTokenStartIndex();
}
stat_seq
{
if ($e.result==1) {
input.seek(loopHead);
doWhileStatement();
}
}
'ENDDO')
;
for the record here are some of the other commands I've written:
(ignore the code written in brackets, it's for the generation of the commands in a text file.)
stat_seq
:
(statement)+
;
statement
:
^(':=' ID e=expression) { variables.put($ID.text,e); }
| ^('WRITE' expression)
{
ch.emitRM("LDC",ac,$expression.result,0,"pass the expression value to the ac reg");
ch.emitRO("OUT",ac,0,0,"write out the value of ac");
}
| ^('READ' ID)
{
ch.emitRO("IN",ac,0,0,"read value");
}
| ^('IF' expression 'THEN'
{
ch.emitRM("LDC",ac1,$expression.result,0,"pass the expression result to the ac reg");
int savedLoc1 = ch.emitSkip(1);
}
sseq1=stat_seq
'ELSE'
{
int savedLoc2 = ch.emitSkip(1);
ch.emitBackup(savedLoc1);
ch.emitRM("JEQ",ac1,savedLoc2+1,0,"skip as many places as needed depending on the expression");
ch.emitRestore();
}
sseq2=stat_seq
{
int savedLoc3 = ch.emitSkip(0);
ch.emitBackup(savedLoc2);
ch.emitRM("LDC",PC_REG,savedLoc3,0,"skip for the else command");
ch.emitRestore();
}
'ENDIF')
| doWhileStatement
;
Any help would be appreciated, thank you
I found it for everyone who has the same problem I did it like this and it's working:
^('WHILE'
{int c = input.index();}
expression
{int s=input.index();}
.* )// .* is a sequence of statements
{
int next = input.index(); // index of node following WHILE
input.seek(c);
match(input, Token.DOWN, null);
pushFollow(FOLLOW_expression_in_statement339);
int condition = expression();
state._fsp--;
//there is a problem here
//expression() seemed to be reading from the grammar file and I couldn't
//get it to read from the tree walker rule somehow
//It printed something like no viable alt at input 'DOWN'
//I googled it and found this mistake
// So I copied the code from the normal while statement
// And pasted it here and it works like a charm
// Normally there should only be int condition = expression()
while ( condition == 1 ) {
input.seek(s);
stat_seq();//stat_seq is a sequence of statements: (statement ';')+
input.seek(c);
match(input, Token.DOWN, null); //Copied value from EvaluatorWalker.java
//cause couldn't find another way to do it
pushFollow(FOLLOW_expression_in_statement339);
condition = expression();
state._fsp--;
System.out.println("condition:"+condition + " i:"+ variables.get("i"));
}
input.seek(next);
}
I wrote the problem at the comments of my code. If anyone can help me out and answer this for me how to do it I would be grateful. It's so weird that there is nearly no feedback on a correct way to implement loops within a tree grammar on the fly.
Regards,
Alex

Resources