Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to
LinuxQuestions.org , a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free.
Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please
contact us . If you need to reset your password,
click here .
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a
virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month.
Click here for more info.
07-31-2014, 12:47 AM
#31
Senior Member
Registered: Sep 2006
Posts: 1,424
Original Poster
Rep:
I don't understand it's output exactly...
07-31-2014, 12:54 AM
#32
Senior Member
Registered: Sep 2006
Posts: 1,424
Original Poster
Rep:
I just got the syntax to work, "I think", by changing the rules to the following:
Code:
if_statement: IF LEFTP expression
{
conprint("a\n");
}
RIGHTP stmt
{
conprint("b\n");
}
| if_statement ELSE stmt
{
conprint("c\n");
}
;
Now, if that is correct syntax, I can begin generating code for the output...
07-31-2014, 09:17 AM
#33
Senior Member
Registered: Sep 2006
Posts: 1,424
Original Poster
Rep:
I still can't do it without being able to detect whether or not there is an else there or not. Unfortunately, this does NOT work...
Code:
if_statement: IF LEFTP expression
{
++ifcounter;
String if_body_str = "if_body_";
if_body_str += ifcounter - 1;
labelTable.insert();
labelTable[labelTable.length() - 1].name(if_body_str);
labelTable[labelTable.length() - 1].address(labelTable.length() - 2);
conprint("ALOAD TBOOLEAN %s\n", $3.to_boolean().get().getString().c_str());
conprint("CGOTOL TVOID %u\n", (ifcounter - 1));
conprint("GOTOL TVOID %u\n", ifcounter);
conprint("\n\nLBL TVOID 0V\n");
}
RIGHTP stmt
{
// Code for if will be inserted here...
cout << elsebegin << endl;
if (yychar == ELSE)
{
String else_body_str = "else_body_";
else_body_str += ifcounter;
String after_if_str = "after_if_";
after_if_str += ifcounter + 1;
labelTable.insert();
labelTable[labelTable.length() - 1].name(else_body_str);
labelTable[labelTable.length() - 1].address(labelTable.length() - 2);
labelTable.insert();
labelTable[labelTable.length() - 1].name(after_if_str);
labelTable[labelTable.length() - 1].address(labelTable.length() - 2);
conprint("GOTOL TVOID %u\n", ifcounter + 1);
}
else
{
String after_if_str = "after_if_";
after_if_str += ifcounter;
labelTable.insert();
labelTable[labelTable.length() - 1].name(after_if_str);
labelTable[labelTable.length() - 1].address(labelTable.length() - 2);
conprint("GOTOL TVOID %u\n", ifcounter);
}
conprint("\n\nLBL TVOID 0V\n");
}
| if_statement ELSE stmt
{
// Code for else will be inserted here if exists...
conprint("GOTOL TVOID %u\n", ifcounter + 1);
conprint("\n\nLBL TVOID 0V\n");
}
;
07-31-2014, 09:44 AM
#34
Senior Member
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,874
By the way, many years ago I did play with bison, too, here is a file I found under the dust:
percpars.y
07-31-2014, 10:03 PM
#35
Senior Member
Registered: Sep 2006
Posts: 1,424
Original Poster
Rep:
So here is my code now:
Code:
if_statement: IF LEFTP expression
{
++ifcounter;
String if_body_str = "if_body_";
if_body_str += ifcounter - 1;
labelTable.insert();
labelTable[labelTable.length() - 1].name(if_body_str);
labelTable[labelTable.length() - 1].address(labelTable.length() - 2);
conprint("ALOAD TBOOLEAN %s\n", $3.to_boolean().get().getString().c_str());
conprint("CGOTOL TVOID %u\n", (ifcounter - 1));
conprint("GOTOL TVOID %u\n", ifcounter);
conprint("\n\nLBL TVOID 0V\n");
}
RIGHTP stmt
{
// Code for if will be inserted here...
ifbegin = outcount;
String after_if_str = "after_if_";
after_if_str += ifcounter;
labelTable.insert();
labelTable[labelTable.length() - 1].name(after_if_str);
labelTable[labelTable.length() - 1].address(labelTable.length() - 2);
conprint("GOTOL TVOID %u\n", ifcounter);
endifbegin = outcount - 1;
conprint("\n\nLBL TVOID 0V\n");
}
| if_statement ELSE stmt
{
// Code for else will be inserted here if exists...
elsebegin = outcount;
String else_body_str = "else_body_";
else_body_str += ifcounter;
String after_if_str = "after_if_";
after_if_str += ifcounter;
labelTable.remove();
labelTable.insert();
labelTable[labelTable.length() - 1].name(else_body_str);
labelTable[labelTable.length() - 1].address(labelTable.length() - 2);
labelTable.insert();
labelTable[labelTable.length() - 1].name(after_if_str);
labelTable[labelTable.length() - 1].address(labelTable.length() - 2);
char temp[33];
ltoa((ifcounter + 1), temp, 10);
String temp2 = "GOTOL TVOID ";
temp2 += temp;
temp2 += "\n";
out[endifbegin] = temp2;
conprint("GOTOL TVOID %u\n", ifcounter + 1);
conprint("\n\nLBL TVOID 0V\n");
}
;
But it doesn't work with an if-else ladder yet. It works with all the rest, but not an if else ladder. Code is where it's supposed to be, but the label numbers in the goto statements are off. For example, given this file:
Code:
if (3 + 2)
;
else if (false)
;
It will generate this code:
Code:
VERSION TVOID 0V
ALOAD TBOOLEAN true
CGOTOL TVOID 0
GOTOL TVOID 1
LBL TVOID 0V
VOID TVOID 0V
GOTOL TVOID 1
LBL TVOID 0V
ALOAD TBOOLEAN false
CGOTOL TVOID 1
GOTOL TVOID 2
LBL TVOID 0V
VOID TVOID 0V
GOTOL TVOID 3
LBL TVOID 0V
GOTOL TVOID 3
LBL TVOID 0V
END TVOID 0V
When it should be generating this code:
Code:
VERSION TVOID 0V
ALOAD TBOOLEAN true
CGOTOL TVOID 0
GOTOL TVOID 3
LBL TVOID 0V
VOID TVOID 0V
GOTOL TVOID 4
LBL TVOID 0V
ALOAD TBOOLEAN false
CGOTOL TVOID 2
GOTOL TVOID 3
LBL TVOID 0V
VOID TVOID 0V
GOTOL TVOID 3
LBL TVOID 0V
GOTOL TVOID 4
LBL TVOID 0V
END TVOID 0V
07-31-2014, 11:33 PM
#36
Senior Member
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,874
That's because 'ifcounter' is a global variable, so the nested if changes its value.
Edit: You can use the parser's stack to save/restore values, eg:
Code:
if: IF { $$.ifcounter= ++ifcounter;
++ifnest;
fprintf (stderr, "line %ld: before if, set ifcounter to %d, nest=%d\n",
lineno, ifcounter, ifnest);
fflush (stderr); }
'(' expr ')' stmt
opt_else { $$.obj = ...;
ifcounter= $2.ifcounter;
--ifnest;
fprintf (stderr, "line %ld: after if, reset ifcounter to %d, ifnest=%d\n",
lineno, ifcounter, ifnest);
fflush (stderr); };
opt_else: { $$.obj = NULL; }
| ELSE stmt { $$.obj = $2.obj; };
Last edited by NevemTeve; 08-01-2014 at 09:21 AM .
08-01-2014, 04:42 PM
#37
Senior Member
Registered: Sep 2006
Posts: 1,424
Original Poster
Rep:
I got a little further by moving the ifcounter code. Now it compiles to the following:
Code:
VERSION TVOID 0V
ALOAD TBOOLEAN true
CGOTOL TVOID 0
GOTOL TVOID 1
LBL TVOID 0V
VOID TVOID 0V
GOTOL TVOID 0
LBL TVOID 0V
ALOAD TBOOLEAN false
CGOTOL TVOID 0
GOTOL TVOID 1
LBL TVOID 0V
VOID TVOID 0V
GOTOL TVOID 3
LBL TVOID 0V
GOTOL TVOID 3
LBL TVOID 0V
END TVOID 0V
Still wrong, but closer in the fact that it is incremented in a lot better spot...
08-07-2014, 11:10 PM
#38
Senior Member
Registered: Sep 2006
Posts: 1,424
Original Poster
Rep:
Trying to use NevemTeve's suggestion, I now have the following code:
Code:
control_statement: if_statement { ++ifcounter; }
;
if_statement: IF LEFTP expression
{
cout << "if p1: " << ifcounter << endl;
String if_body_str = "if_body_";
if_body_str += ifcounter;
labelTable.insert();
labelTable[labelTable.length() - 1].name(if_body_str);
labelTable[labelTable.length() - 1].address(labelTable.length() - 2);
conprint("ALOAD TBOOLEAN %s\n", $3.to_boolean().get().getString().c_str());
conprint("CGOTOL TVOID %u\n", ifcounter);
conprint("GOTOL TVOID %u\n", ifcounter + 1);
conprint("\n\nLBL TVOID 0V\n");
}
RIGHTP stmt
{
cout << "if p2: " << ifcounter << endl;
// Code for if will be inserted here...
ifbegin = outcount;
String after_if_str = "after_if_";
after_if_str += ifcounter;
labelTable.insert();
labelTable[labelTable.length() - 1].name(after_if_str);
labelTable[labelTable.length() - 1].address(labelTable.length() - 2);
conprint("GOTOL TVOID %u\n", ifcounter);
endifbegin = outcount - 1;
conprint("\n\nLBL TVOID 0V\n");
}
opt_else
;
opt_else: | ELSE stmt
{
cout << "else: " << ifcounter << endl;
// Code for else will be inserted here if exists...
elsebegin = outcount;
String else_body_str = "else_body_";
else_body_str += ifcounter;
String after_if_str = "after_if_";
after_if_str += ifcounter;
labelTable.remove();
labelTable.insert();
labelTable[labelTable.length() - 1].name(else_body_str);
labelTable[labelTable.length() - 1].address(labelTable.length() - 2);
labelTable.insert();
labelTable[labelTable.length() - 1].name(after_if_str);
labelTable[labelTable.length() - 1].address(labelTable.length() - 2);
char temp[33];
ltoa((ifcounter + 2), temp, 10);
String temp2 = "GOTOL TVOID ";
temp2 += temp;
temp2 += "\n";
out[endifbegin] = temp2;
conprint("GOTOL TVOID %u\n", ifcounter + 2);
conprint("\n\nLBL TVOID 0V\n");
}
;
The output of the program looks okay when run with an if or an if-else:
Code:
if p1: 0
if p2: 0
else: 0
...But not an if-else ladder:
Code:
if p1: 0
if p2: 0
if p1: 0
if p2: 0
else: 1
It should be:
Code:
if p1: 0
if p2: 0
if p1: 1
if p2: 1
else: 0
ifcounter is supposed to count the number of if's in the code. Based off of that, I generate the if statement code.
08-07-2014, 11:23 PM
#39
Senior Member
Registered: Sep 2006
Posts: 1,424
Original Poster
Rep:
I got the ifcounter to work, but surprisingly, it still doesn't work. Given:
Code:
if (3 + 2)
;
else if (false)
;
It generates:
Code:
VERSION TVOID 0V
ALOAD TBOOLEAN true
CGOTOL TVOID 0
GOTOL TVOID 1
LBL TVOID 0V
VOID TVOID 0V
GOTOL TVOID 0
LBL TVOID 0V
ALOAD TBOOLEAN false
CGOTOL TVOID 1
GOTOL TVOID 2
LBL TVOID 0V
VOID TVOID 0V
GOTOL TVOID 2
LBL TVOID 0V
GOTOL TVOID 2
LBL TVOID 0V
END TVOID 0V
The code should be as stated before.
---------- Post added 08-07-14 at 09:24 PM ----------
Maybe an ifnest is needed?
08-07-2014, 11:33 PM
#40
Senior Member
Registered: Sep 2006
Posts: 1,424
Original Poster
Rep:
ifnest now works, and count up by one if there is an if-else statement in an if-else statement...
08-08-2014, 01:42 AM
#41
Senior Member
Registered: Sep 2006
Posts: 1,424
Original Poster
Rep:
Now it gets tricker...
Here is my code:
Code:
control_statement: if_statement
;
if_statement: IF LEFTP expression
{
++ifcounter;
ifgoto = ifcounter < 2 ? ifcounter : ifcounter + 1;
cout << "if p1: " << ifcounter << " " << ifnest << " " << " " << elsecounter << ifgoto << endl;
String if_body_str = "if_body_";
if_body_str += ifgoto - 1;
labelTable.insert();
labelTable[labelTable.length() - 1].name(if_body_str);
labelTable[labelTable.length() - 1].address(labelTable.length() - 2);
conprint("ALOAD TBOOLEAN %s\n", $3.to_boolean().get().getString().c_str());
conprint("CGOTOL TVOID %u\n", ifgoto - 1);
conprint("GOTOL TVOID %u\n", ifgoto);
conprint("\n\nLBL TVOID 0V\n");
}
RIGHTP stmt
{
cout << "if p2: " << ifcounter << " " << ifnest << " " << elsecounter << " " << ifgoto << endl;
// Code for if will be inserted here...
ifbegin = outcount;
String after_if_str = "after_if_";
after_if_str += ifgoto - 1;
labelTable.insert();
labelTable[labelTable.length() - 1].name(after_if_str);
labelTable[labelTable.length() - 1].address(labelTable.length() - 2);
conprint("GOTOL TVOID %u\n", ifgoto - 1);
endifbegin = outcount - 1;
conprint("\n\nLBL TVOID 0V\n");
}
opt_else
{
--ifcounter;
++ifnest;
}
;
opt_else: | ELSE stmt
{
++elsecounter;
cout << "else: " << ifcounter << " " << ifnest << " " << elsecounter << " " << ifgoto << endl;
// Code for else will be inserted here if exists...
elsebegin = outcount;
String else_body_str = "else_body_";
else_body_str += ifcounter;
String after_if_str = "after_if_";
after_if_str += ifgoto - 1;
labelTable.remove();
labelTable.insert();
labelTable[labelTable.length() - 1].name(else_body_str);
labelTable[labelTable.length() - 1].address(labelTable.length() - 2);
labelTable.insert();
labelTable[labelTable.length() - 1].name(after_if_str);
labelTable[labelTable.length() - 1].address(labelTable.length() - 2);
char temp[33];
ltoa((ifgoto + 1), temp, 10);
String temp2 = "GOTOL TVOID ";
temp2 += temp;
temp2 += "\n";
out[endifbegin] = temp2;
ifgoto = elsecounter >= 2 ? ifgoto + 1 : ifgoto;
conprint("GOTOL TVOID %u\n", ifgoto + 1);
conprint("\n\nLBL TVOID 0V\n");
}
;
It generates code correctly in this case:
Code:
if (3 + 2)
;
else if (false)
;
...and in this case:
Code:
if (3 + 2)
;
else if (false)
;
else
;
...but NOT in this case:
Code:
if (3 + 2)
{
;
}
else if (false)
{
;
}
else
;
In the last case, it generates:
Code:
VERSION TVOID 0V
ALOAD TBOOLEAN true
CGOTOL TVOID 0
GOTOL TVOID 1
LBL TVOID 0V
VOID TVOID 0V
GOTOL TVOID 0
LBL TVOID 0V
ALOAD TBOOLEAN false
CGOTOL TVOID 2
GOTOL TVOID 3
LBL TVOID 0V
VOID TVOID 0V
GOTOL TVOID 4
LBL TVOID 0V
VOID TVOID 0V
GOTOL TVOID 4
LBL TVOID 0V
GOTOL TVOID 5
LBL TVOID 0V
END TVOID 0V
When the result should be:
Code:
VERSION TVOID 0V
ALOAD TBOOLEAN true
CGOTOL TVOID 0
GOTOL TVOID 1
LBL TVOID 0V
VOID TVOID 0V
GOTOL TVOID 4
LBL TVOID 0V
ALOAD TBOOLEAN false
CGOTOL TVOID 2
GOTOL TVOID 3
LBL TVOID 0V
VOID TVOID 0V
GOTOL TVOID 4
LBL TVOID 0V
VOID TVOID 0V
GOTOL TVOID 4
LBL TVOID 0V
GOTOL TVOID 5
LBL TVOID 0V
END TVOID 0V
08-08-2014, 03:44 AM
#42
Senior Member
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,874
It would be an improvement if you used a pseudo-Assembly that actually made sense.
Code:
if (10==20+30) {
x= 1;
}
LD $r1,10
LD $r2,20
LD $r3,30
ADD $r2,$r3
SUB $r1,$r2
BNZ LABEL_1
LD $r1,1
ST $r1,x
LABEL_1:
08-08-2014, 06:57 AM
#43
LQ Guru
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,679
Why do you think that the rest of us are so dammed
interested in watching you debug your compiler?
Why don't you crack-open
any book (Ajo or some other, simpler one) that just
shows you how it's done? And, be done??
08-08-2014, 06:19 PM
#44
Senior Member
Registered: Sep 2006
Posts: 1,424
Original Poster
Rep:
Here's the documentation for the lower level language(s).
08-08-2014, 06:34 PM
#45
Senior Member
Registered: Sep 2006
Posts: 1,424
Original Poster
Rep:
I have it compiled to the asm of this language. I am creating a whole set of tools for this language. The intent way down the road is to make it easier to create a whole operating system. Although still very difficult, it's easier to create a program in the lowest level than it is to directly write java bytecode or machine language or an .exe or an elf file.
This language can be as portable as Java, but it is easier to write at it's lowest level, and should be nearly or just as fast. It comes with tools to compile it to native code. The assembler, is a step easier than this language. Then there's this high-level language I'm developing, which is a step easier than the assembler. Then eventually, I'll probably write some code on top of this to make that easier, and so on, so that it is really powerful and easy to use.
All times are GMT -5. The time now is 10:09 PM .
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know .
Latest Threads
LQ News