How to Check If a variable identifier is not declared

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

How to Check If a variable identifier is not declared

peterxu422
On page 238, at the bottom there is an assumption "When compiling error-free Jack code, any identifier not found in the symbol table may be assumed to be a subroutine name or a class name."

But what if your Jack code is not error-free. How do you build the compiler so that it can check whether a variable identifier is used but not declared? Originally, the way I checked it was to take the identifier and check it in my Symbol Tables. Suppose it returned an index of -1, I would know that it is not in the table and thus the variable was not declared. But if I follow the assumption above, how do I differentiate between non-declared variable identifiers and className/subroutineName identifiers?

I'm running into problems with CompileTerm(), whose grammar is:
- term: integerConstant|stringConstant|keywordConstant|varName|varName '[' expression ']' | subroutineCall | '(' expression ')' | unaryOp term
- subroutineCall: subroutineName '(' expressionList ')' | (className | varName) '.' subroutineName '(' expressionList ')'

My algorithm for part with identifiers is:
check identifier //checks for varName, subroutineName, or className
advance token
checks for symbols '[', '(', '.'

My problem occurs at the check identifier because I don't know ahead of time whether it is a varName, subroutineName, or className, so if I check if it exists in the Symbol Table and it tells me no, then I can't tell if it's a varName that's undeclared or if it's a class/subName.

Any suggestions for a fix?
Reply | Threaded
Open this post in threaded view
|

Re: How to Check If a variable identifier is not declared

cadet1620
Administrator
peterxu422 wrote
My problem occurs at the check identifier because I don't know ahead of time whether it is a varName, subroutineName, or className, so if I check if it exists in the Symbol Table and it tells me no, then I can't tell if it's a varName that's undeclared or if it's a class/subName.
Since you are writing a one-pass compiler, there is no way to know what external class names will be available when the VM translator combines all the VM files generated by the Jack sources in the current directory.

Since all fields and variables must be defined in Jack before they are used, any undefined symbol you encounter at this point is either a class/subroutine name or an error that the compiler cannot detect. The compiler must assume that the symbol is a class/subroutine name and generate VM code for the call.

If the symbol is not a valid external name, the VM translator will generate ASM code that references the bad name. The VM Emulator will catch this error, but the assembler will assign a RAM address to the bogus symbol, which will result in a program bug or crash.

To properly report this error your compiler would need to scan all the other Jack files in the current directory and include their classes and functions/methods in the symbol table, and it would need to know about the OS classes and functions/methods.

--Mark