Can anyone tell me how to print a parse tree in Perl? I can get the file read and everything. What I am doing is building a syntax checker, but only for parentheses. When I read in an open parentheses, I push it to the stack. When I read a close parentheses, I pop it from the stack. But, as I am doing this, I print out the parse tree to an output file. The input file looks like this:
OPAREN (
DEFUN Defun
NAME Acount
OPAREN (
NAME L
CPAREN )
OPAREN (
COND Cond
OPAREN (
...
etc.
The parse tree should look like this:
OPAREN (
DEFUN Defun
NAME Acount
OPAREN (
NAME L
CPAREN )
OPAREN (
COND Cond
OPAREN (
...
etc.
The problem I am having is printing the tabs right to get it to go to the next level in the tree. I was told if there were, for example, 5 items on the stack, print 5 tabs or something like that. I do not know how to do that, as I am not that familiar with the Perl stack. Thanks for any input.
Comments
: The problem I am having is printing the tabs right to get it to go to the next level in the tree. I was told if there were, for example, 5 items on the stack, print 5 tabs or something like that. I do not know how to do that, as I am not that familiar with the Perl stack. Thanks for any input.
:
I don't know Perl, but there is a simple (but maybe not elegant) solution:
You can have a counter variable, which should be increased by 1 every time you push something, and decreased by 1 every time you pop something from the stack. Thus it reflects current size of the stack.
:
: OPAREN (
: DEFUN Defun
: NAME Acount
: OPAREN (
: NAME L
: CPAREN )
: OPAREN (
: COND Cond
: OPAREN (
: ...
: etc.
:
: The parse tree should look like this:
:
: OPAREN (
: DEFUN Defun
: NAME Acount
: OPAREN (
: NAME L
: CPAREN )
: OPAREN (
: COND Cond
: OPAREN (
: ...
: etc.
:
: The problem I am having is printing the tabs right to get it to go to the next level in the tree. I was told if there were, for example, 5 items on the stack, print 5 tabs or something like that. I do not know how to do that, as I am not that familiar with the Perl stack. Thanks for any input.
:
If the array holding your stack was called, for example, @stack, then you could do (before printing the line):-
print " " x scalar(@stack);
To print X tabs when there are X items on the stack.
Jonathan
###
for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
(tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
/(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");
: :
: : OPAREN (
: : DEFUN Defun
: : NAME Acount
: : OPAREN (
: : NAME L
: : CPAREN )
: : OPAREN (
: : COND Cond
: : OPAREN (
: : ...
: : etc.
: :
: : The parse tree should look like this:
: :
: : OPAREN (
: : DEFUN Defun
: : NAME Acount
: : OPAREN (
: : NAME L
: : CPAREN )
: : OPAREN (
: : COND Cond
: : OPAREN (
: : ...
: : etc.
: :
: : The problem I am having is printing the tabs right to get it to go to the next level in the tree. I was told if there were, for example, 5 items on the stack, print 5 tabs or something like that. I do not know how to do that, as I am not that familiar with the Perl stack. Thanks for any input.
: :
: If the array holding your stack was called, for example, @stack, then you could do (before printing the line):-
:
: print " " x scalar(@stack);
:
: To print X tabs when there are X items on the stack.
:
: Jonathan
:
: ###
: for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
: (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
: /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");
:
:
: : :
: : : OPAREN (
: : : DEFUN Defun
: : : NAME Acount
: : : OPAREN (
: : : NAME L
: : : CPAREN )
: : : OPAREN (
: : : COND Cond
: : : OPAREN (
: : : ...
: : : etc.
: : :
: : : The parse tree should look like this:
: : :
: : : OPAREN (
: : : DEFUN Defun
: : : NAME Acount
: : : OPAREN (
: : : NAME L
: : : CPAREN )
: : : OPAREN (
: : : COND Cond
: : : OPAREN (
: : : ...
: : : etc.
: : :
: : : The problem I am having is printing the tabs right to get it to go to the next level in the tree. I was told if there were, for example, 5 items on the stack, print 5 tabs or something like that. I do not know how to do that, as I am not that familiar with the Perl stack. Thanks for any input.
: : :
: : If the array holding your stack was called, for example, @stack, then you could do (before printing the line):-
: :
: : print " " x scalar(@stack);
: :
: : To print X tabs when there are X items on the stack.
: :
: : Jonathan
: :
: : ###
: : for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
: : (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
: : /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");
: :
: :
:
I am not sure what you mean by the array that holds my stack. Here is my code:
[CODE]
@lines = ;
close(INPUT);
foreach $line (@lines) {
@fields = split(/ /, $line);
if ($fields[0] eq 'OPAREN') {
print OUTPUT "$fields[0] ";
print OUTPUT "$fields[1]";
push(@fields, $fields[1]);
}elsif ($fields[0] eq 'CPAREN') {
print OUTPUT "$fields[0] ";
print OUTPUT "$fields[1]";
pop(@fields);
}elsif (($fields[0] ne 'OPAREN') && ($fields[0] ne 'CPAREN')) {
print OUTPUT "$fields[0] ";
print OUTPUT "$fields[1]";
}
}
[/CODE]
It still has a couple of bugs but I don't know how else to split it up. Thanks for the help.
:
: : : :
: : : : OPAREN (
: : : : DEFUN Defun
: : : : NAME Acount
: : : : OPAREN (
: : : : NAME L
: : : : CPAREN )
: : : : OPAREN (
: : : : COND Cond
: : : : OPAREN (
: : : : ...
: : : : etc.
: : : :
: : : : The parse tree should look like this:
: : : :
: : : : OPAREN (
: : : : DEFUN Defun
: : : : NAME Acount
: : : : OPAREN (
: : : : NAME L
: : : : CPAREN )
: : : : OPAREN (
: : : : COND Cond
: : : : OPAREN (
: : : : ...
: : : : etc.
: : : :
: : : : The problem I am having is printing the tabs right to get it to go to the next level in the tree. I was told if there were, for example, 5 items on the stack, print 5 tabs or something like that. I do not know how to do that, as I am not that familiar with the Perl stack. Thanks for any input.
: : : :
: : : If the array holding your stack was called, for example, @stack, then you could do (before printing the line):-
: : :
: : : print " " x scalar(@stack);
: : :
: : : To print X tabs when there are X items on the stack.
: : :
: : : Jonathan
: : :
: : : ###
: : : for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
: : : (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
: : : /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");
: : :
: : :
: :
: I am not sure what you mean by the array that holds my stack.
Not sure how I can explain it any other way, but in the case of your code it's @fields.
: Here is my code:
: [CODE]
: @lines = ;
:
: close(INPUT);
:
: foreach $line (@lines) {
: @fields = split(/ /, $line);
: if ($fields[0] eq 'OPAREN') {
: print OUTPUT "$fields[0] ";
: print OUTPUT "$fields[1]";
: push(@fields, $fields[1]);
: }elsif ($fields[0] eq 'CPAREN') {
: print OUTPUT "$fields[0] ";
: print OUTPUT "$fields[1]";
: pop(@fields);
: }elsif (($fields[0] ne 'OPAREN') && ($fields[0] ne 'CPAREN')) {
: print OUTPUT "$fields[0] ";
: print OUTPUT "$fields[1]";
: }
: }
: [/CODE]
:
: It still has a couple of bugs but I don't know how else to split it up. Thanks for the help.
: :
:
:
###
for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
(tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
/(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");
: : : : :
: : : : : OPAREN (
: : : : : DEFUN Defun
: : : : : NAME Acount
: : : : : OPAREN (
: : : : : NAME L
: : : : : CPAREN )
: : : : : OPAREN (
: : : : : COND Cond
: : : : : OPAREN (
: : : : : ...
: : : : : etc.
: : : : :
: : : : : The parse tree should look like this:
: : : : :
: : : : : OPAREN (
: : : : : DEFUN Defun
: : : : : NAME Acount
: : : : : OPAREN (
: : : : : NAME L
: : : : : CPAREN )
: : : : : OPAREN (
: : : : : COND Cond
: : : : : OPAREN (
: : : : : ...
: : : : : etc.
: : : : :
: : : : : The problem I am having is printing the tabs right to get it to go to the next level in the tree. I was told if there were, for example, 5 items on the stack, print 5 tabs or something like that. I do not know how to do that, as I am not that familiar with the Perl stack. Thanks for any input.
: : : : :
: : : : If the array holding your stack was called, for example, @stack, then you could do (before printing the line):-
: : : :
: : : : print " " x scalar(@stack);
: : : :
: : : : To print X tabs when there are X items on the stack.
: : : :
: : : : Jonathan
: : : :
: : : : ###
: : : : for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
: : : : (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
: : : : /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");
: : : :
: : : :
: : :
: : I am not sure what you mean by the array that holds my stack.
: Not sure how I can explain it any other way, but in the case of your code it's @fields.
:
: : Here is my code:
: : [CODE]
: : @lines = ;
: :
: : close(INPUT);
: :
: : foreach $line (@lines) {
: : @fields = split(/ /, $line);
: : if ($fields[0] eq 'OPAREN') {
: : print OUTPUT "$fields[0] ";
: : print OUTPUT "$fields[1]";
: : push(@fields, $fields[1]);
: : }elsif ($fields[0] eq 'CPAREN') {
: : print OUTPUT "$fields[0] ";
: : print OUTPUT "$fields[1]";
: : pop(@fields);
: : }elsif (($fields[0] ne 'OPAREN') && ($fields[0] ne 'CPAREN')) {
: : print OUTPUT "$fields[0] ";
: : print OUTPUT "$fields[1]";
: : }
: : }
: : [/CODE]
: :
: : It still has a couple of bugs but I don't know how else to split it up. Thanks for the help.
: : :
: :
: :
I fixed it some more again but the tabs still do not print right. Here's what I changed:
[CODE]
foreach $line (@lines) {
@fields = split(/ /, $line);
if ($fields[0] eq 'OPAREN') {
print OUTPUT " " x scalar(@stack);
@stack = push(@fields, $fields[1]);
print OUTPUT "$fields[0] ";
print OUTPUT "$fields[1]";
}elsif ($fields[0] eq 'CPAREN') {
print OUTPUT " " x scalar(@stack);
$temp = pop(@fields);
print OUTPUT "$fields[0] ";
print OUTPUT "$temp";
}else {
print OUTPUT " " x scalar(@stack);
print OUTPUT "$fields[0] ";
print OUTPUT "$fields[1]";
}
}
[/CODE]
Thanks for the input.
:
:
: ###
: for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
: (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
: /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");
:
:
: : : : : :
: : : : : : OPAREN (
: : : : : : DEFUN Defun
: : : : : : NAME Acount
: : : : : : OPAREN (
: : : : : : NAME L
: : : : : : CPAREN )
: : : : : : OPAREN (
: : : : : : COND Cond
: : : : : : OPAREN (
: : : : : : ...
: : : : : : etc.
: : : : : :
: : : : : : The parse tree should look like this:
: : : : : :
: : : : : : OPAREN (
: : : : : : DEFUN Defun
: : : : : : NAME Acount
: : : : : : OPAREN (
: : : : : : NAME L
: : : : : : CPAREN )
: : : : : : OPAREN (
: : : : : : COND Cond
: : : : : : OPAREN (
: : : : : : ...
: : : : : : etc.
: : : : : :
: : : : : : The problem I am having is printing the tabs right to get it to go to the next level in the tree. I was told if there were, for example, 5 items on the stack, print 5 tabs or something like that. I do not know how to do that, as I am not that familiar with the Perl stack. Thanks for any input.
: : : : : :
: : : : : If the array holding your stack was called, for example, @stack, then you could do (before printing the line):-
: : : : :
: : : : : print " " x scalar(@stack);
: : : : :
: : : : : To print X tabs when there are X items on the stack.
: : : : :
: : : : : Jonathan
: : : : :
: : : : : ###
: : : : : for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
: : : : : (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
: : : : : /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");
: : : : :
: : : : :
: : : :
: : : I am not sure what you mean by the array that holds my stack.
: : Not sure how I can explain it any other way, but in the case of your code it's @fields.
: :
: : : Here is my code:
: : : [CODE]
: : : @lines = ;
: : :
: : : close(INPUT);
: : :
: : : foreach $line (@lines) {
: : : @fields = split(/ /, $line);
: : : if ($fields[0] eq 'OPAREN') {
: : : print OUTPUT "$fields[0] ";
: : : print OUTPUT "$fields[1]";
: : : push(@fields, $fields[1]);
: : : }elsif ($fields[0] eq 'CPAREN') {
: : : print OUTPUT "$fields[0] ";
: : : print OUTPUT "$fields[1]";
: : : pop(@fields);
: : : }elsif (($fields[0] ne 'OPAREN') && ($fields[0] ne 'CPAREN')) {
: : : print OUTPUT "$fields[0] ";
: : : print OUTPUT "$fields[1]";
: : : }
: : : }
: : : [/CODE]
: : :
: : : It still has a couple of bugs but I don't know how else to split it up. Thanks for the help.
: : : :
: : :
: : :
: I fixed it some more again but the tabs still do not print right. Here's what I changed:
:
: [CODE]
:
: foreach $line (@lines) {
: @fields = split(/ /, $line);
: if ($fields[0] eq 'OPAREN') {
: print OUTPUT " " x scalar(@stack);
: @stack = push(@fields, $fields[1]);
: print OUTPUT "$fields[0] ";
: print OUTPUT "$fields[1]";
: }elsif ($fields[0] eq 'CPAREN') {
: print OUTPUT " " x scalar(@stack);
: $temp = pop(@fields);
: print OUTPUT "$fields[0] ";
: print OUTPUT "$temp";
: }else {
: print OUTPUT " " x scalar(@stack);
: print OUTPUT "$fields[0] ";
: print OUTPUT "$fields[1]";
: }
: }
: [/CODE]
: Thanks for the input.
: :
: :
I only posted an example. You have to use your own variables in it! So
print OUTPUT " " x scalar(@stack);
Should be:-
print OUTPUT " " x scalar(@fields);
Jonathan
###
for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
(tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
/(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");