private bool CheckValidVariableAssignment(string lexeme)
 {
     if (!(SymbolTable.LookupNode(lexeme) is VariableNode))
     {
         CommonTools.PromptProgramErrorExit($"ERROR: Line {LexicalAnaylzer.LineNumber} Invalid " +
                                            $"assignment to {lexeme}");
         return(false);
     }
     return(true);
 }
 // Checks if an identifier exists as a variable node in symbol table and is in scope
 private bool CheckDeclaredVariable()
 {
     if (SymbolTable.LookupNode(LexicalAnaylzer.Lexeme) == null)
     {
         CommonTools.PromptProgramErrorExit($"ERROR: Line {LexicalAnaylzer.LineNumber} Use of " +
                                            $"undeclared variable {LexicalAnaylzer.Lexeme}");
         return(false);
     }
     return(true);
 }
 // Inserts a node into symbol table and prints error if insertion failure
 private bool InsertNode(Node node)
 {
     if (!SymbolTable.InsertNode(node))
     {
         CommonTools.PromptProgramErrorExit($"ERROR: Line {LexicalAnaylzer.LineNumber} " +
                                            $"Duplicate lexeme \"{node.Lexeme}\" with depth \"{node.Depth}\" exists");
         return(false);
     }
     return(true);
 }
        // OutputOptions -> IdentifierToken | StringLiteralToken | EndLineToken
        private bool ProcessOutputOptions()
        {
            if (LexicalAnaylzer.Token == Token.IdentifierToken)
            {
                VariableNode node = (VariableNode)SymbolTable.LookupNode(LexicalAnaylzer.Lexeme);
                if (node == null)
                {
                    CommonTools.PromptProgramErrorExit($"ERROR: Line {LexicalAnaylzer.LineNumber} Use of " +
                                                       $"undeclared variable \"{LexicalAnaylzer.Lexeme}\"");
                    return(false);
                }

                if (node.Type == Token.CharToken)
                {
                    OutputThreeAddressCode($"\t_WRC {GetThreeAddressCodeName(LexicalAnaylzer.Lexeme)}");
                }
                else if (node.Type == Token.IntToken)
                {
                    OutputThreeAddressCode($"\t_WRI {GetThreeAddressCodeName(LexicalAnaylzer.Lexeme)}");
                }
                else
                {
                    OutputThreeAddressCode($"\t_WRF {GetThreeAddressCodeName(LexicalAnaylzer.Lexeme)}");
                }
                LexicalAnaylzer.GetNextToken();
            }
            else if (LexicalAnaylzer.Token == Token.StringLiteralToken)
            {
                StringLiteralNode node = new StringLiteralNode()
                {
                    Lexeme  = $"_S{SymbolTable.StringLiteralCount}",
                    Literal = LexicalAnaylzer.Lexeme
                };
                SymbolTable.InsertNode(node);
                OutputThreeAddressCode($"\t_WRS {node.Lexeme}");
                LexicalAnaylzer.GetNextToken();
            }
            else
            {
                OutputThreeAddressCode($"\t_WRL");
                if (!MatchToken(Token.EndLineToken))
                {
                    return(false);
                }
            }
            return(true);
        }
        public bool Start()
        {
            bool programCorrect = ProcessProgram() && CheckMainDeclared();

            if (LexicalAnaylzer.Token != Token.EndOfFileToken && programCorrect)
            {
                CommonTools.PromptProgramErrorExit(
                    $"ERROR: Line {LexicalAnaylzer.LineNumber} " +
                    $"Unexpected tokens in source file, expected End-of-File Token");
            }

            if ((CommonTools.ThreeAddressCodeRun) && programCorrect)
            {
                CommonTools.WriteOutput(ThreeAddressCodeOutput);
            }
            return(programCorrect);
        }
        // InputStatement -> CharacterInToken RightShiftOperatorToken IdentifierToken InputEnd
        private bool ProcessInputStatement()
        {
            if (!MatchToken(Token.CharacterInToken))
            {
                return(false);
            }
            if (!MatchToken(Token.RightShiftOperatorToken))
            {
                return(false);
            }

            VariableNode node = (VariableNode)SymbolTable.LookupNode(LexicalAnaylzer.Lexeme);

            if (node == null)
            {
                CommonTools.PromptProgramErrorExit($"ERROR: Line {LexicalAnaylzer.LineNumber} Use of " +
                                                   $"undeclared variable \"{LexicalAnaylzer.Lexeme}\"");
                return(false);
            }
            if (node.Type == Token.CharToken)
            {
                OutputThreeAddressCode($"\t_RDC {GetThreeAddressCodeName(LexicalAnaylzer.Lexeme)}");
            }
            else if (node.Type == Token.IntToken)
            {
                OutputThreeAddressCode($"\t_RDI {GetThreeAddressCodeName(LexicalAnaylzer.Lexeme)}");
            }
            else
            {
                OutputThreeAddressCode($"\t_RDF {GetThreeAddressCodeName(LexicalAnaylzer.Lexeme)}");
            }

            if (!MatchToken(Token.IdentifierToken))
            {
                return(false);
            }
            if (!ProcessInputEnd())
            {
                return(false);
            }
            return(true);
        }
 // Displays expected tokens error to appropriate displays
 private void DisplayExpectedTokensError(string expectedToken)
 {
     CommonTools.PromptProgramErrorExit($"ERROR: Line {LexicalAnaylzer.LineNumber} Expected token " +
                                        $"\"{expectedToken}\" - Received token \"{LexicalAnaylzer.Token}\"");
 }
        // Returns the three address code variable name of the given lexeme
        private string GetThreeAddressCodeName(string lexeme)
        {
            decimal n;

            if (decimal.TryParse(lexeme, out n))
            {
                string temporaryVariable;
                int    x;
                if (int.TryParse(lexeme, out x))
                {
                    temporaryVariable = GetTemporaryVariableName(Token.IntToken);
                }
                else
                {
                    temporaryVariable = GetTemporaryVariableName(Token.FloatToken);
                }

                OutputThreeAddressCode($"\t{temporaryVariable} = {SignOperation}{lexeme}");
                SignOperation = string.Empty;
                return(temporaryVariable);
            }

            Node node = SymbolTable.LookupNode(lexeme);

            if (node is VariableNode)
            {
                if (node.Depth == GlobalConfiguration.BaseDepth)
                {
                    return($"_{lexeme}");
                }
                else
                {
                    return($"_BP" + ((VariableNode)node).Offset.ToString("+0;-#"));
                }
            }
            else if (node is ConstantNode)
            {
                string temporaryVariable;
                if ((((ConstantNode)node).Value != null))
                {
                    temporaryVariable = GetTemporaryVariableName(Token.IntToken);
                }
                else
                {
                    temporaryVariable = GetTemporaryVariableName(Token.FloatToken);
                }

                string outputvalue = (((ConstantNode)node).Value ?? ((ConstantNode)node).ValueReal).ToString();
                OutputThreeAddressCode($"\t{temporaryVariable} = {SignOperation}{outputvalue}");
                SignOperation = string.Empty;
                return(temporaryVariable);
            }
            else if (node is FunctionNode)
            {
                CommonTools.PromptProgramErrorExit($"ERROR: Line {LexicalAnaylzer.LineNumber} Invalid use function {node.Lexeme}");
                return(string.Empty);
            }
            else
            {
                return(lexeme);
            }
        }