Handling the double ")"

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

Handling the double ")"

pawdwanlearner
Ok so i am implementing the 1st part of chapter 10 and im using the SquareGame.jack code to test my compilation engine. in the while statement i am running into the problem of handling
 while (~(key = 0)) {
            let key = Keyboard.keyPressed();
            do moveSquare();
the double )) here is causing an error for me my code is below

def compileExpression(self):
        #compiles and expression
        while self.tokenizer.currentToken() != ";":
            self.compileTerm()  #compiles the current term
            if self.tokenizer.currentToken() != ";":
                self.makeEntry()
                           
        return

my code recognizes the ; but not the ) especially if its a )) like above any hints on this.
Reply | Threaded
Open this post in threaded view
|

Re: Handling the double ")"

cadet1620
Administrator
This post was updated on .
Your problem here is that the expression does not end with a ';'. It ends with a ')'.
while ( ~(key = 0) ) {
    while body
}
Instead of the while loop breaking on ';' it needs break if the current token (after calling compileTerm) is not an operator.

Since expression always starts with a term and is followed by 0 or more (operator term) pairs, I structure this loop as

compileTerm()
while tokenizer.token is an operator {
    handle operator
    compileTerm()
}

When compiling while (~(key = 0)) the while loop in the above code does not run because ~(key = 0) is a term and is handled by the compileTerm() call before the while loop.

(compileTerm does recursively call compileExpression, and that inner execution does enter the while loop while handling key = 0.)

 

FWIW, in tokenizing code I write comments that include the syntax that I'm compiling and where the tokenizer is expected to be on entry and exit. It helps me remember what's supposed to be happening when I'm writing the code. (If my coding wasn't always bug free, they might help in debugging it too 8^)

    def _CompileExpression(self):
        """
        Compiles <expression> :=
            <term> (<op> <term>)*

        ENTRY: Tokenizer positioned on the expression.
        EXIT:  Tokenizer positioned after the expression.
        """
        self._WriteXmlTag('<expression>\n')

--Mark

Reply | Threaded
Open this post in threaded view
|

Re: Handling the double ")"

pawdwanlearner
Thanks cadet !! I decided to follow the suggestion of the book and take a step back and make sure the expressionless analyzer works first before trying to incorporate expression compiling. One question when you said i should make a loop that continues if an operator did you mean only op's or op's and unary ops.
Reply | Threaded
Open this post in threaded view
|

Re: Handling the double ")"

cadet1620
Administrator
pawdwanlearner wrote
One question when you said i should make a loop that continues if an operator did you mean only op's or op's and unary ops.
Oops. That comment has been wrong for years. It should say
Compiles <expression> :=
    <term> (<op> <term>)*
since it specifically means the op syntax rule.

The while loop is looking for operators that can join two terms which are just the op symbols:
<op> := '+' | '-' | '*' | '/' | '&' | '|' | '<' | '>' | '='

If you included unaryOp you would allow the expression "a ~ b" which isn't part of the grammar.

--Mark
 
Reply | Threaded
Open this post in threaded view
|

Re: Handling the double ")"

pawdwanlearner
Thanks for that Cadet. (where you in the military?) anyway i was taking another look at the grammar and i see that the "this" keyword is also a keyword Constant. is this correct or some kind of typo.Trying to rectify it in my code.
Reply | Threaded
Open this post in threaded view
|

Re: Handling the double ")"

cadet1620
Administrator
Yes, "this" is a keyword constant.  It's there so that you can "return this" at the end of a constructor and "do Memory.deAlloc(this)" in a dispose method.

(Never in the military. See my bio which explains Cadet1620.)

--Mark
Reply | Threaded
Open this post in threaded view
|

Re: Handling the double ")"

pawdwanlearner
My hats off to you your one of the pioneers, a triple OOOG from back in the day much respect and thanks for helping us out here.
Reply | Threaded
Open this post in threaded view
|

Re: Handling the double ")"

pawdwanlearner
Finished with lexical analysis now on to chapter 11 Exciting to see the the text comparater pass my xml.  Alice and wonderland ain't got nothing on a deeply nested syntax tree.
Reply | Threaded
Open this post in threaded view
|

Re: Handling the double ")"

cadet1620
Administrator
Congratulations.

When you add the VmWriter in project 11, you might want to leave the XML writing code in place.  It can really help to know exactly where the parser was when your VmWriter crashes...

(My finished compiler has XML file generation controlled by a -x command line option, default to off.)

--Mark
Reply | Threaded
Open this post in threaded view
|

Re: Handling the double ")"

Krozu
In reply to this post by pawdwanlearner
pawdwanlearner wrote
Alice and wonderland ain't got nothing on a deeply nested syntax tree.
I'm going to be quoting that from now on if you don't mind.
Reply | Threaded
Open this post in threaded view
|

Re: Handling the double ")"

daniel4422
In reply to this post by cadet1620
Hi guys,
I have followed your threat cause I am also facing an issue with the double ").
my problem is different - I do not know how to access the "parent term" in order to write the ')' correctly in the XML, maybe it is a code issue I don't know (I am using python + ElementTree).
Example of the problem :
As you can see, the ')' symbol is being written after the last created '<term>' :

                                                <term>
                                                        <symbol>(</symbol>
                                                        <expression>
                                                                <term>
                                                                        <symbol>(</symbol>
                                                                        <expression>
                                                                                <term>
                                                                                        <identifier>y</identifier>
                                                                                </term>
                                                                                <symbol>+</symbol>
                                                                                <term>
                                                                                        <identifier>size</identifier>
                                                                                        <symbol>)</symbol>
                                                                                </term>

  instead of :

                <term>
                  <symbol> ( </symbol>
                  <expression>
                    <term>
                      <identifier> y </identifier>
                    </term>
                    <symbol> + </symbol>
                    <term>
                      <identifier> size </identifier>
                    </term>
                  </expression>
                  <symbol> ) </symbol>
                </term>


my code is as follows, I guess I do not know where to put the while ')' to exit the term correctly. or maybe it because I am using self.term which save the last object...

    def CompileTerm(self):
        self.term = ET.SubElement(self.expression,'term')
        ET.SubElement(self.term,self.CurrentToken[1]).text = self.CurrentToken[0]
        if self.CurrentToken[0] in ('(','['):
            while not(self.CurrentToken[0]==')'):
                self.HasMoreToken()
                self.CompileExpression(self.term)
        if self.CurrentToken[1]=='identifier':

    def CompileExpression(self,parent):
        self.expression= ET.SubElement(parent,'expression')
        self.CompileTerm()
        self.HasMoreToken()
        while self.CurrentToken[0] in oplst :
            ET.SubElement(self.expression,self.CurrentToken[1]).text = self.CurrentToken[0]
            self.HasMoreToken()
            self.CompileTerm()
            self.HasMoreToken()