Ejemplo n.º 1
0
        private void RunButton_Click(object sender, RoutedEventArgs e)
        {
            txtOutput.Text = "";            //reset output text
            Input          = txtInput.Text; //reset input text to new text
            ListOfTokens.Clear();           //reset table

            getTokens(Input);

            if (Flag) //check if there is an error
            {
                foreach (TokenReg token in ListOfTokens)
                {
                    txtOutput.Text += token.ToString();
                }

                //Parser program
                try
                {
                    removeCommentTokens(); //remove comment tokens from list as we dont need them in the parsing process
                    Parser     p = new Parser(ListOfTokens);
                    SyntaxTree s = p.program();

                    TreeViewItem treeViewItem = makeTreeView(s);
                    Window1      secondWindow = new Window1();
                    secondWindow.mainTreeView.Items.Add(treeViewItem);
                    secondWindow.Show();
                }
                catch (ParsingErrorException ex)
                {
                    MessageBox.Show(ex.Message, ex.Source,
                                    MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }
Ejemplo n.º 2
0
 private void removeCommentTokens()
 {
     for (int i = 0; i < ListOfTokens.Count; i++)
     {
         if (ListOfTokens.ElementAt(i).Token == TokenReg.TOKEN_TYPE.T_COMMENT)
         {
             ListOfTokens.Remove(ListOfTokens.ElementAt(i));
         }
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// takes a string as input and divides it into lexemes and tokens adding them into the listOfTokens variable
        /// </summary>
        /// <param name="input">input string to compute</param>
        private void getTokens(string input)
        {
            Flag = true; //this variable indicates that the function finished succesfully with no errors
            int   j = 0; //integer to keep track of the first index of the lexeme
            int   i;     //integer to keep track of the last index of the lexeme
            STATE currentState = STATE.Start;

            for (i = 0; i < input.Length; i++)
            {
                try
                {
                    switch (currentState)
                    {
                    case STATE.Start:
                        j = i;      //to keep track of the first element's index
                        if (isLetter(input.ElementAt(i)))
                        {
                            if (i == input.Length - 1)     //we do this check to not neglect the last letter
                            {
                                i--;
                            }
                            currentState = STATE.Identifier;
                        }
                        else if (isDigit(input.ElementAt(i)))
                        {
                            if (i == input.Length - 1)     //we do this check to not neglect the last digit
                            {
                                i--;
                            }
                            currentState = STATE.Num1;
                        }
                        else if (isWhiteSpace(input.ElementAt(i)))
                        {
                            //do nothing
                        }
                        else if (input.ElementAt(i) == '/')
                        {
                            if (i == input.Length - 1)
                            {
                                i--;
                            }
                            currentState = STATE.Comment1;
                        }
                        else if (input.ElementAt(i) == '"')
                        {
                            currentState = STATE.String;
                        }
                        else if (input.ElementAt(i) == '(')
                        {
                            ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_LEFTBRACKET, "("));
                        }
                        else if (input.ElementAt(i) == ')')
                        {
                            ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_RIGHTBRACKET, ")"));
                        }
                        else if (input.ElementAt(i) == ';')
                        {
                            ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_SEMICOLON, ";"));
                        }
                        else if (input.ElementAt(i) == ',')
                        {
                            ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_COMMA, ","));
                        }
                        else if (input.ElementAt(i) == '+')
                        {
                            ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_PLUS, "+"));
                        }
                        else if (input.ElementAt(i) == '-')
                        {
                            ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_MINUS, "-"));
                        }
                        else if (input.ElementAt(i) == '*')
                        {
                            ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_MULTIPLICATION, "*"));
                        }
                        else if (input.ElementAt(i) == ':')
                        {
                            if (input.ElementAt(i + 1) == '=')
                            {
                                ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_ASSIGN, ":="));
                                i++;     //we increment i to skip the equal sign evaluation
                            }
                            else
                            {
                                i--;                        //to catch the symbol that did the error
                                currentState = STATE.error; //since the colon char is never used alone it must always accompany the equal sign
                            }
                        }
                        else if (input.ElementAt(i) == '=')
                        {
                            ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_EQUAL, "="));
                        }
                        else if (input.ElementAt(i) == '<')
                        {
                            if (input.ElementAt(i + 1) == '>')
                            {
                                listOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_NOTEQUAL, "<>"));
                                i++;     //we increment i to skip the > evaluation
                            }
                            else
                            {
                                ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_LESSTHAN, "<"));
                            }
                        }
                        else if (input.ElementAt(i) == '>')
                        {
                            ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_GREATERTHAN, ">"));
                        }
                        else if (input.ElementAt(i) == '&')
                        {
                            if (input.ElementAt(i + 1) == '&')
                            {
                                ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_AND, "&&"));
                                i++;     //we increment i to skip the & evaluation
                            }
                            else
                            {
                                currentState = STATE.error;     //same as the assign lexeme
                            }
                        }
                        else if (input.ElementAt(i) == '|')
                        {
                            if (input.ElementAt(i + 1) == '|')
                            {
                                ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_OR, "||"));
                                i++;     //we increment i to skip the | evaluation
                            }
                            else
                            {
                                currentState = STATE.error;     //same as the assign lexeme
                            }
                        }
                        else if (input.ElementAt(i) == '{')
                        {
                            ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_LEFTBRACE, "{"));
                        }
                        else if (input.ElementAt(i) == '}')
                        {
                            ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_RIGHTBRACE, "}"));
                        }
                        else
                        {
                            i--;                        //we decrement it as if it was the last index in the string we wouldnt cycle back to indicate an error occured
                            currentState = STATE.error; //anything else is out of the alphabet and therefore an error
                        }
                        break;

                    case STATE.Num1:
                        if (isDigit(input.ElementAt(i)) && i != input.Length - 1)
                        {
                            //do nothing
                        }
                        else if (input.ElementAt(i) == '.')
                        {
                            if (i == input.Length - 1)
                            {
                                i--;                        //decrement to not go out of loop
                                currentState = STATE.error; //because you cant end string with dot
                            }
                            else
                            {
                                currentState = STATE.Num2;
                            }
                        }
                        else if (isLetter(input.ElementAt(i)))
                        {
                            if (i == input.Length - 1)
                            {
                                i--;
                            }
                            currentState = STATE.error;     //if a letter follows a number without another delimeter that means that this was supposed to be an invalid identifier and therefore we move it to the error state.
                        }
                        else
                        {
                            if (!isDigit(input.ElementAt(i))) //if last character in string is digit then we dont decrement the i
                            {
                                i--;                          //we decrement i as we do not want to include the [other] character in our number
                            }
                            ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_NUMBER, input.Substring(j, i - j + 1)));
                            currentState = STATE.Start;     //go back to start state to accept new token
                        }
                        break;

                    case STATE.Num2:
                        if (isDigit(input.ElementAt(i)))
                        {
                            if (i == input.Length - 1)     //we do this check to not neglect the last number after the dot
                            {
                                i--;
                            }
                            currentState = STATE.Num3;
                        }
                        else
                        {
                            if (i == input.Length - 1)     //we do this check to not neglect the last symbol after the dot and advance to the error state
                            {
                                i--;
                            }
                            currentState = STATE.error;     //as we dont expect anything other than a digit to follow
                        }
                        break;

                    case STATE.Num3:
                        if (isDigit(input.ElementAt(i)) && i != input.Length - 1)
                        {
                            //do nothing
                        }
                        else if (isLetter(input.ElementAt(i)))
                        {
                            if (i == input.Length - 1)
                            {
                                i--;
                            }
                            currentState = STATE.error;     //if a letter follows a number without another delimeter that means that this was supposed to be an invalid identifier and therefore we move it to the error state.
                        }
                        else
                        {
                            if (!isDigit(input.ElementAt(i)))
                            {
                                i--;     //we decrement i as we do not want to include the [other] character in our number
                            }
                            ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_NUMBER, input.Substring(j, i - j + 1)));
                            currentState = STATE.Start;     //go back to start state to accept new token
                        }
                        break;

                    case STATE.Identifier:
                        if ((isLetter(input.ElementAt(i)) || isDigit(input.ElementAt(i))) && i != input.Length - 1)     // i != input.Length - 1 to make sure that the last lexeme is taken into consideration without doing nothing
                        {
                            //do nothing
                        }
                        else
                        {
                            if (!(isLetter(input.ElementAt(i)) || isDigit(input.ElementAt(i))))           //we dont want to decrement i if it is the last character of a lexeme so we make that check
                            {
                                i--;                                                                      //we decrement i as we do not want to include the [other] character in our identifier
                            }
                            TokenReg.TOKEN_TYPE tokenVal = isReservedWord(input.Substring(j, i - j + 1)); //we check if it is one of the reserved keywords first and register it in the tokenVal variable, if its not token Val will have a value of T_ID
                            ListOfTokens.AddLast(new TokenReg(tokenVal, input.Substring(j, i - j + 1)));
                            currentState = STATE.Start;                                                   //go back to start state to accept new token
                        }
                        break;

                    case STATE.String:
                        if (input.ElementAt(i) == '"')
                        {
                            ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_STRINGVAL, input.Substring(j + 1, i - j - 1))); //we put the start of substring as j + 1 to ignore the quotation marks; same thing for i - j - 1 instead of i - j + 1
                            currentState = STATE.Start;                                                                             //go back to start state to accept new token
                        }
                        break;

                    case STATE.Comment1:
                        if (input.ElementAt(i) == '*')
                        {
                            currentState = STATE.Comment2;
                        }
                        else
                        {
                            if (input.ElementAt(i) != '/')
                            {
                                i--;                                                                 //as we just want the division lexeme so we decrement and go back to start state
                            }
                            ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_DIVISION, "/")); //as there was a / character and another character other than * appeared then we consider it as a division symbol rather than the start of a comment
                            currentState = STATE.Start;                                              //go back to start state to accept new token
                        }
                        break;

                    case STATE.Comment2:
                        if (input.ElementAt(i) == '*')
                        {
                            currentState = STATE.Comment3;
                        }
                        break;

                    case STATE.Comment3:
                        if (input.ElementAt(i) == '/')
                        {
                            ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_COMMENT, input.Substring(j, i - j + 1)));
                            currentState = STATE.Start;     //go back to start state to accept new token
                        }
                        else if (input.ElementAt(i) == '*')
                        {
                            //do nothing
                        }
                        else
                        {
                            currentState = STATE.Comment2;
                        }
                        break;

                    case STATE.error:
                        string errorString = input.Substring(0, i + 1);      //split the string from start to where the error occured
                        int    numLines    = errorString.Split('\n').Length; //get the number of lines of where the error occured
                        txtOutput.Text = "error at line " + numLines + ".";
                        Flag           = false;                              //indicating that an error has occured
                        return;
                    }
                }
                catch (ArgumentOutOfRangeException)
                {
                    if (input.ElementAt(i) == '<')
                    {
                        ListOfTokens.AddLast(new TokenReg(TokenReg.TOKEN_TYPE.T_LESSTHAN, "<"));
                    }
                    else
                    {
                        if (i == input.Length - 1)
                        {
                            i--; //to not get out of loop before going to error state
                        }
                        currentState = STATE.error;
                    }
                }
            }
        }