Example #1
0
 private bool Analyze()
 {
     PrintStackAndInput();
     while (true)
     {
         PrintStackAndInput();
         char stack_symb = PopFromStack();
         if (stack_symb == emptyProduction)
         {
             continue;
         }
         Lexema lexema       = input.peekLexema();
         char   seqence_symb = lexema.symbol;
         if (stack_symb == seqence_symb)
         {
             if (stack_symb == stopSymbol)
             {
                 Console.WriteLine("String is perfect.");
                 return(true);
             }
             else
             {
                 input.get();            //отстранява се следващия символ от потока
             }
         }
         else
         {
             //предполага се, че символа, взет от стека, е нетерминален
             //търсене на нетерм. символ в table_entry
             Hashtable table_entry = (Hashtable)productionsTable[stack_symb];
             if (table_entry != null)
             {
                 //търсене на продукция за замяна на нетерм. символ
                 String production = (String)table_entry[seqence_symb];
                 if (production != null)
                 {
                     //към стека се добавя нужната продукция
                     PushIntoStack(production);
                     PrintProduction(stack_symb, production);
                 }
                 else
                 {
                     //не съществува продукция, за да получим stack_symb => seqence_symb
                     SyntaxError(String.Format("Не съществува продукция {0} => {1}",
                                               stack_symb, seqence_symb), lexema.row);
                     return(false);
                 }
             }
             else
             {
                 //няма такъв нетерминален символ или това е терминален символ,
                 //различен от този във входната редица
                 SyntaxError(String.Format("Символът от стека '{0}' е терминален " +
                                           "и не съвпада със символа от входната редица: '(1)' " +
                                           "или е нетерминален и не образува продукции", stack_symb, seqence_symb), lexema.row);
                 return(false);
             }
         }
     }
 }
Example #2
0
        public Lexema getLexema()
        {
            Lexema lexema = peekLexema();

            position++;
            return(lexema);
        }
Example #3
0
 private bool changeSymbol(LexemaSequence input, Lexema lexema, char search_symbol,
                           char replace_symbol)
 {
     if (lexema.symbol == search_symbol)
     {
         if (input.GetPosition() > 1)
         {
             if (input.getLexema(input.GetPosition() - 2).symbol == Expression.IDENTIFIER)
             {
                 lexema.symbol = replace_symbol;
                 return(true);
             }
         }
         if (input.GetPosition() < input.size())
         {
             if (input.peekLexema().symbol == Expression.IDENTIFIER)
             {
                 //това е префиксна операция, не се прави заместване
                 return(true);
             }
             else
             {
                 Console.WriteLine(search_symbol + " can be applyed only to identifier.");
                 return(false);
             }
         }
         Console.WriteLine("Error 1002.");
         return(false);
     }
     else
     {
         return(true);
     }
 }
Example #4
0
 private void checkUnaryMinus(LexemaSequence input, Lexema lexema)
 {
     if (lexema.symbol == Expression.MINUS)
     {
         bool must_change = false;
         if (input.GetPosition() > 1)
         {
             char symbol = input.getLexema(input.GetPosition() - 2).symbol;
             if ((symbol == Expression.ASSIGNMENT) ||
                 (symbol == Expression.OPEN_BRACE) ||
                 (symbol == Expression.PLUS) ||
                 (symbol == Expression.MULTUPLICATION) ||
                 (symbol == Expression.BITWISE_OR) ||
                 (symbol == Expression.DIVISION) ||
                 (symbol == Expression.MODUL) ||
                 (symbol == Expression.BITWISE_AND) ||
                 (symbol == Expression.BITWISE_INVERSION) ||
                 (symbol == Expression.BOOLEAN_INVERSION))
             {
                 must_change = true;
             }
         }
         else
         {
             must_change = true;
         }
         if (must_change)
         {
             lexema.symbol = Expression.UNARY_MINUS;
         }
     }
 }
Example #5
0
        //открива и заменя постфиксни ++ и -- с други символи
        private bool incAndDecSymbolDeal(LexemaSequence input, Lexema lexema)
        {
            bool ret = true;

            ret = changeSymbol(input, lexema, Expression.PREFIX_INCREMENT, Expression.POSTFIX_INCREMENT);
            if (ret == true)
            {
                ret = changeSymbol(input, lexema, Expression.PREFIX_DECREMENT, Expression.POSTFIX_DECREMENT);
            }
            return(ret);
        }
Example #6
0
 public Lexema pop()
 {
     if (lexemas.Count > 0)
     {
         Lexema ret = (Lexema)lexemas[lexemas.Count - 1];
         lexemas.RemoveAt(lexemas.Count - 1);
         return(ret);
     }
     else
     {
         return(null);
     }
 }
Example #7
0
 private bool parseStatements()
 {
     //входната поредица ще се обработва израз по израз (разделени са с ';')
     try
     {
         asmCode = asmHeader;
         input.rewind();
         int       input_size = input.size();
         Statement stmt       = new Statement();
         for (int i = 0; i < input_size; i++)
         {
             Lexema lexema = input.getLexema();
             if (lexema.symbol != Expression.SEMICOLON)
             {
                 incAndDecSymbolDeal(input, lexema);
                 checkUnaryMinus(input, lexema);
                 if (stmt.convertIntoRPN(lexema) == false)
                 {
                     return(false);
                 }
             }
             else
             {
                 //прехвърля всичко от стека на изходната редица
                 ArrayList postfix_expressions = stmt.completeRPN(); //<Lexema>
                 //израза се преобразува в асемблерен код
                 asmCode += stmt.generateAsembler();
                 //добавя се израза, съдържащ само постфиксни оператори
                 if (postfix_expressions.Count != 0)
                 {
                     Statement postfix_stmt = new Statement(postfix_expressions);
                     //израза се преобразува в асемблерен код
                     asmCode += postfix_stmt.generateAsembler();
                 }
                 stmt = new Statement();
             }
         }
         asmCode += returnDOS;
         asmCode += writeIncludedProcs();
         asmCode += asmFooter;
         Console.WriteLine("\nASSEMBLER CODE:\n" + asmCode);
     }
     catch (Exception ex)
     {
         Console.WriteLine(ex.StackTrace);
         return(false);
     }
     return(true);
 }
Example #8
0
        //връща последователността от лексеми от текущата позиция до края
        public override String ToString()
        {
            String      symbol_sequence = "";
            int         pos             = 0;
            IEnumerator iter            = sequence.GetEnumerator();

            while (iter.MoveNext())
            {
                Lexema lexema = (Lexema)iter.Current;
                if (pos >= position)
                {
                    symbol_sequence += lexema.symbol;
                }
                pos++;
            }
            return(symbol_sequence);
        }
Example #9
0
 private String getAddressOrValue(Lexema lexema)
 {
     if (lexema.symbol == intermediateLexemaSymbol)
     {
         //това е on-the-fly стойност
         return(String.Format(savePlace, lexema.address));
     }
     else if (lexema.symbol == Expression.IDENTIFIER)
     {
         return(String.Format("dword ptr [ebp+{0}]", lexema.address));
     }
     else if (lexema.symbol == Expression.NUMBER)
     {
         return(lexema.value.ToString());
     }
     else
     {
         throw new Exception("Error 1005: no match found for symbol: " +
                             lexema.symbol);
     }
 }
Example #10
0
            private bool assignmentSignDeal()
            {
                //претърсват се символите от входната редица и ако има различни
                //от идентификатор или знак '=' значи има семантична грешка
                IEnumerator iter = stmt.GetEnumerator();    //<Lexema>

                while (iter.MoveNext())
                {
                    Lexema lexema = (Lexema)iter.Current;
                    if ((lexema.symbol != Expression.ASSIGNMENT) &&
                        (lexema.symbol != Expression.IDENTIFIER) &&
                        (lexema.symbol != Expression.OPEN_BRACE) &&
                        (lexema.symbol != Expression.CLOSE_BRACE))
                    {
                        Console.WriteLine("Left of assigment sign '=' can be only" +
                                          " identifier.");
                        return(false);
                    }
                }
                return(true);
            }
Example #11
0
            //генерира асмеблерен код за целия израз (statement)
            public String generateAsembler()
            {
                Asembler    asm     = new Asembler();
                String      asmCode = "";
                IEnumerator iter    = stmt.GetEnumerator(); //<Lexema>

                while (iter.MoveNext())
                {
                    Lexema     lexema          = (Lexema)iter.Current;
                    Expression expression_sign = (Expression)expressions[lexema.symbol];
                    //ако поредния символ е операнд го пишем в стека
                    if (expression_sign == null)
                    {
                        stack.push(lexema);
                    }

                    //това е оператор, може да е унарен или да работи с две стойности
                    Asembler.Result result = asm.processSingleOperation(lexema);
                    if (result != null)
                    {
                        asmCode += result.code;
                        if (result.savedIn == Asembler.Result.IN_SAVE_PLACE)
                        {
                            //индикация, че на тази позиция има нещо,
                            //чиято стойност е вече сметната
                            //и трябва да се вземе например от програмния стек
                            stack.push(new Lexema(intermediateLexemaSymbol, 0,
                                                  getLastAddress(), Lexema.NO_VALUE));
                        }
                    }
                }
                //TODO: провери дали стека е празен, защото ако не е празен и
                //израза не е бил само с постфиксни оператори значи има грешка
                stack.clear();
                Console.WriteLine("CODE FOR STATEMENT: " + this.ToString() + "\n" + asmCode + "\n");
                return(asmCode);
            }
Example #12
0
 public void push(Lexema lexema)
 {
     lexemas.Add(lexema);
 }
Example #13
0
                //генерира асемблерен код за единичен оператор
                public Result processSingleOperation(Lexema lexema)
                {
                    switch (lexema.symbol)
                    {
                    case Expression.PLUS:
                    {
                        Lexema right_side_lexema = stack.pop();
                        Lexema left_side_lexema  = stack.pop();
                        return(new Result(doPlus(getAddressOrValue(right_side_lexema),
                                                 getAddressOrValue(left_side_lexema)), Result.IN_SAVE_PLACE));
                    }

                    case Expression.ASSIGNMENT:
                    {
                        Lexema right_side_lexema = stack.pop();
                        Lexema left_side_lexema  = stack.peek();
                        return(new Result(doAssignment(getAddressOrValue(right_side_lexema),
                                                       getAddressOrValue(left_side_lexema)), Result.IN_MEMORY));
                    }

                    case Expression.MINUS:
                    {
                        Lexema right_side_lexema = stack.pop();
                        Lexema left_side_lexema  = stack.pop();
                        return(new Result(doMinus(getAddressOrValue(right_side_lexema),
                                                  getAddressOrValue(left_side_lexema)), Result.IN_SAVE_PLACE));
                    }

                    case Expression.PREFIX_INCREMENT:
                    case Expression.POSTFIX_INCREMENT:
                    {
                        Lexema only_side_lexema = stack.peek();
                        return(new Result(doIncrement(getAddressOrValue(only_side_lexema)),
                                          Result.IN_MEMORY));
                    }

                    case Expression.PREFIX_DECREMENT:
                    case Expression.POSTFIX_DECREMENT:
                    {
                        Lexema only_side_lexema = stack.peek();
                        return(new Result(doDecrement(getAddressOrValue(only_side_lexema)),
                                          Result.IN_MEMORY));
                    }

                    case Expression.BITWISE_INVERSION:
                    {
                        Lexema only_side_lexema = stack.pop();
                        return(new Result(doBitwiseInversion(getAddressOrValue(only_side_lexema)),
                                          Result.IN_SAVE_PLACE));
                    }

                    case Expression.BITWISE_AND:
                    {
                        Lexema right_side_lexema = stack.pop();
                        Lexema left_side_lexema  = stack.pop();
                        return(new Result(doBitwiseAnd(getAddressOrValue(right_side_lexema),
                                                       getAddressOrValue(left_side_lexema)), Result.IN_SAVE_PLACE));
                    }

                    case Expression.BITWISE_OR:
                    {
                        Lexema right_side_lexema = stack.pop();
                        Lexema left_side_lexema  = stack.pop();
                        return(new Result(doBitwiseOr(getAddressOrValue(right_side_lexema),
                                                      getAddressOrValue(left_side_lexema)), Result.IN_SAVE_PLACE));
                    }

                    case Expression.BOOLEAN_INVERSION:
                    {
                        Lexema only_side_lexema = stack.pop();
                        return(new Result(doBooleanInversion(getAddressOrValue(only_side_lexema)),
                                          Result.IN_SAVE_PLACE));
                    }

                    case Expression.UNARY_MINUS:
                    {
                        Lexema only_side_lexema = stack.pop();
                        return(new Result(doUnaryMinus(getAddressOrValue(only_side_lexema)),
                                          Result.IN_SAVE_PLACE));
                    }

                    case Expression.MULTUPLICATION:
                    {
                        Lexema right_side_lexema = stack.pop();
                        Lexema left_side_lexema  = stack.pop();
                        return(new Result(doMultiplication(getAddressOrValue(right_side_lexema),
                                                           getAddressOrValue(left_side_lexema)), Result.IN_SAVE_PLACE));
                    }

                    case Expression.DIVISION:
                    {
                        Lexema right_side_lexema = stack.pop();
                        Lexema left_side_lexema  = stack.pop();
                        return(new Result(doDivision(getAddressOrValue(right_side_lexema),
                                                     getAddressOrValue(left_side_lexema)), Result.IN_SAVE_PLACE));
                    }

                    case Expression.MODUL:
                    {
                        Lexema right_side_lexema = stack.pop();
                        Lexema left_side_lexema  = stack.pop();
                        return(new Result(doModul(getAddressOrValue(right_side_lexema),
                                                  getAddressOrValue(left_side_lexema)), Result.IN_SAVE_PLACE));
                    }

                    case Expression.PRINTF:
                    {
                        Lexema only_side_lexema = stack.pop();
                        return(new Result(doPrintf(getAddressOrValue(only_side_lexema)),
                                          Result.IN_MEMORY));
                    }

                    case Expression.SCANF:
                    {
                        stack.pop();
                        return(new Result(doScanf(),
                                          Result.IN_SAVE_PLACE));
                    }
                    }
                    return(null);
                }
Example #14
0
            public bool convertIntoRPN(Lexema lexema)
            {
                Expression expression_sign = (Expression)expressions[lexema.symbol];

                //ако поредния символ е операнд или константа го пишем направо на изходната редица
                if (expression_sign == null)
                {
                    stmt.Add(lexema);
                }
                else
                {
                    //това е оператор
                    if (expression_sign.symbol == Expression.CLOSE_BRACE)
                    {
                        //затварящата скоба предизвиква изхвърляне на символи от стека
                        //докато се срещне отваряща скоба. Двете се унищожават.
                        //взима се лексемата от върха на стека
                        Lexema TOS_lexema = stack.peek();
                        //проверка за празен стек
                        if (TOS_lexema != null)
                        {
                            //стекът не е празен
                            Expression TOS_expression_sign = (Expression)expressions[TOS_lexema.symbol];
                            while (TOS_expression_sign.symbol != Expression.OPEN_BRACE)
                            {
                                //предизвиква се изхвърляне на символи от стека към изходната редица
                                TOS_lexema = stack.pop();
                                stmt.Add(TOS_lexema);
                                //поглежда се какъв е следващия символ от стека
                                TOS_lexema = stack.peek();
                                if (TOS_lexema != null)
                                {
                                    TOS_expression_sign = (Expression)expressions[TOS_lexema.symbol];
                                }
                                else
                                {
                                    //стекът вече е празен
                                    Console.WriteLine("ERROR 1000: " +
                                                      "Can not find open brace while executing RPN");
                                    return(false);
                                }
                            }
                            //премахва се отварящата скоба от стека
                            stack.pop();
                        }
                        else
                        {
                            Console.WriteLine("ERROR 1001: " +
                                              "Can not find open brace while executing RPN");
                            return(false);
                        }
                    }
                    else
                    {
                        //постфиксните ++ и -- се обработват по различен начин начин
                        if ((expression_sign.symbol == Expression.POSTFIX_INCREMENT) ||
                            (expression_sign.symbol == Expression.POSTFIX_DECREMENT))
                        {
                            //добавя се предишния идентификатор
                            postfix.Add(stmt[stmt.Count - 1]);
                            //добавя се и самата лексема
                            postfix.Add(lexema);
                        }
                        else
                        {
                            //обработват се останалите лексеми
                            //взима се лексемата от върха на стека
                            Lexema TOS_lexema = stack.peek();
                            //проверка за празен стек
                            if (TOS_lexema != null)
                            {
                                //стекът не е празен
                                Expression TOS_expression_sign = (Expression)expressions[TOS_lexema.symbol];
                                while (expression_sign.outOfStackPriority <= TOS_expression_sign.inStackPriority)
                                {
                                    //текъщия символ е с по-нисък или равен приоритет и ще
                                    //предизвика изхвърляне на символи от стека към изходната редица
                                    TOS_lexema = stack.pop();
                                    stmt.Add(TOS_lexema);
                                    //поглежда се какъв е следващия символ от стека
                                    TOS_lexema = stack.peek();
                                    if (TOS_lexema != null)
                                    {
                                        TOS_expression_sign = (Expression)expressions[TOS_lexema.symbol];
                                    }
                                    else
                                    {
                                        break;  //стекът вече е празен
                                    }
                                }
                            }
                            stack.push(lexema);
                        }
                    }
                    if (expression_sign.symbol == Expression.ASSIGNMENT)
                    {
                        if (assignmentSignDeal() == false)
                        {
                            return(false);
                        }
                    }
                }
                return(true);
            }