Anda di halaman 1dari 9

Session Summer2015

Assignment
Design and develop a simple Syntax Directed Translator (SDT)
to check whether the following mathematical expressions are
in the grammar CFG or not. It can also be able to translate an
infix expression into a postfix expression.
These expressions are consisting of only decimal digits [09]
separated with arithmetic binary operators [+,-,*, /] and
parenthesis [(,)].

Prepared for:
Md. Sajjatul Islam
Course Name: Compiler
Course Code: CSE320

Prepared by:
Md. Abdul Kader
Dept: CSE
ID No: 131000812
Submission Date: August 22, 2015
1 | Page

Objectives:
We covered a lot of important things such as all phases of the
compiler, how works lexical analyzer and how the parser produces
syntax tree. We know about the syntax directed translation and how to
attach a CFG with program fragment to the production of a grammar. By
using the knowledge of the compiler, our objective is to create a
program that will be able to validate an arithmetic expression and
converts it to postfix expression.

Tools/Environment that have been used:


To solve the problem I used Microsoft C# console window.

Program:
/*Program for validate arithmetic expression and convert infix to postfix. Ex:
5*(5+5)*/
using System;
namespace CompilerAssignment
{
/*class for execute the program*/
static class Execute
{
/*method for executing the program*/
static void Main()
{
var ie = new InputExpression();
ie.InExp();
}
}
/*class for taking infix expression*/
class InputExpression
{
private string _expression;
public void InExp()
{
Console.Write("Enter Expression: ");
_expression = Console.ReadLine();
var sdt = new Sdtforarithmaticexp();
sdt.Input(_expression);
}
}
/*class for SDT (for validating expression) using CFG*/
class Sdtforarithmaticexp
{
private int _flag;
int[] _terminal;
int _terminalPosition;
int[] _terminalValue;
const int Maxterminal = 100;
const int Maxdigit = 20;
const int ReadAnything = 0;
const int ReadNumber = 1;
/*method for making list of the token*/
void ScanString(string inputstring)

2 | Page

{
var scannerState = ReadAnything;
var readingPosition = 0;
var numberPosition = 0;
var number = new char[Maxdigit];
_terminal = new int[Maxterminal];
_terminalValue = new int[Maxterminal];
_terminal[0] = 'S';
_terminalPosition = 1;
while (readingPosition < inputstring.Length)
{
var currentCharacter = inputstring[readingPosition];
switch (scannerState)
{
case ReadAnything:
if ("0123456789".IndexOf(currentCharacter) >= 0 &&
"0123456789".IndexOf(currentCharacter) < 10)
{
scannerState = ReadNumber;
numberPosition = 0;
}
else if ("()*+".IndexOf(currentCharacter) >= 0 && "()*+".IndexOf(currentCharacter) <= 3 ||
"-".IndexOf(currentCharacter) == 0 || "/".IndexOf(currentCharacter) == 0)
{
_terminal[_terminalPosition++] = currentCharacter;
readingPosition++;
}
else if (currentCharacter == ' ')
readingPosition++;
else
{
Console.Write("Invalid character: {0}\n", currentCharacter);
return;
}
break;
case ReadNumber:
if ("0123456789".IndexOf(currentCharacter) >= 0 &&
"0123456789".IndexOf(currentCharacter) < 10)
{
number[numberPosition++] = Convert.ToChar(currentCharacter);
readingPosition++;
}
else
{
number[numberPosition] = '\0';
_terminal[_terminalPosition] = 'N';
_terminalValue[_terminalPosition++] = Convert.ToInt32(new string(number));
scannerState = ReadAnything;
}
break;
}
}
if (scannerState == ReadNumber)
{
number[numberPosition] = '\0';
_terminal[_terminalPosition] = 'N';
_terminalValue[_terminalPosition++] = Convert.ToInt32(new string(number));
}
}

3 | Page

/*CFG and recursive parsing is used to validate expression*/


/* E -> T|E+T|E-T
T -> F|T*F|T/F
F -> digit|(E)
digit -> 0|1|2|3|4|5|6|7|8|9*/
/*method for evaluate expression*/
int EvaluateExpression()
{
var termValue = EvaluateTerm();
switch (_terminal[_terminalPosition])
{
case '+':
_terminalPosition--;
return EvaluateExpression() + termValue;
case '-':
_terminalPosition--;
return EvaluateExpression() - termValue;
}
return termValue;
}
/*Method for evaluating term*/
int EvaluateTerm()
{
var factorValue = EvaluateFactor();
switch (_terminal[_terminalPosition])
{
case '*':
_terminalPosition--;
return EvaluateTerm() * factorValue;
case '/':
if (factorValue == 0)
{
_flag = 1;
Console.Write("Division by zero\n");
return 0;
}
_terminalPosition--;
return EvaluateTerm() / factorValue;
}
return factorValue;
}
/*Method for evaluating Factor*/
int EvaluateFactor()
{
int numberValue;
switch (_terminal[_terminalPosition])
{
case 'N':
numberValue = _terminalValue[_terminalPosition];
_terminalPosition--;
break;
case ')':
_terminalPosition--;
numberValue = EvaluateExpression();
if (_terminal[_terminalPosition] == '(')
_terminalPosition--;
else
{

4 | Page

_flag = 1;
return 0;

}
break;
default:
_flag = 1;
return 0;

}
return numberValue;
}
/*Method for processing input string and produce output*/
public void Input(string inputstring)
{
ScanString(inputstring);
_terminalPosition--;
var overallValue = EvaluateExpression();
if (_terminalPosition == 0 && _flag == 0)
{
Console.WriteLine("\nResult :: Correct Expression");
var ip = new InfixToPostfix();
ip.Input(inputstring);
Console.Write("\nValue after Evaluation :: {0}\n\n", overallValue);
}
else
Console.Write("Result: Sorry! Syntax error\n");
}

}
/*class for converting infix to postfix expression*/
class InfixToPostfix
{
private string _expstring, _tempPost;
private char[] _post;
private char[] _stack;
int _top = -1, _toper = -1, _flag = 1;
/*method for taking infix expression convert it to postfix expression*/
public void Input(string expstr)
{
int i;
_expstring = expstr;
if (_expstring == null) return;
_expstring += ')';
var len = _expstring.Length;
_post = new char[len];
_stack = new char[len];
_stack[++_toper] = '(';
Console.Write("\n Infix to Postfix Conversion \n");
Console.Write("-------------------------------\n");
Console.Write("\nCharacter\tStack\t Postfix\n");
for (i = 0; i < len; i++)
{
if (_expstring[i] - 48 >= 0 && _expstring[i] - 48 <= 9)
{
Insertpostfix(_expstring[i]);
}
else if (_expstring[i] == '(')
{
Insertstack(_expstring[i]);
}
else if (_expstring[i] == '+' || _expstring[i] == '-' || _expstring[i] == '*' || _expstring[i] == '/')

5 | Page

{
var chk = Checkprec(_expstring[i]);
var chk2 = Checkprec(_stack[_toper]);
if (chk > chk2)
{
Insertstack(_expstring[i]);
}
else
{
Popstack(_expstring[i]);
}
}
else if (_expstring[i] == ')')
{
pop_all();
}
if (_flag != 0)
{
Console.Write("\n(" + (i + 1) + ") " + _expstring[i] + "\t\t");
Console.Write(_stack);
_tempPost = new string(_post);
Console.Write("\t " + _tempPost);
}
else
{
break;
}
}
if (_flag != 0)
Console.Write("\n\nFinal Postfix Notation :: " + _tempPost + "\n");
else
{
Console.WriteLine("\n\nError: Wrong Expression\n");
}

}
/*method for stack (for operand)*/
void Insertpostfix(char x)
{
_top++;
_post[_top] = x;
}
/*method for stack (for operator)*/
void Insertstack(char x)
{
_toper++;
_stack[_toper] = x;
}
/*method for pop out*/
void Popstack(char x)
{
_top++;
_post[_top] = _stack[_toper];
_stack[_toper] = x;
}
/*method for pop out element from the stack*/
void pop_all()
{
try
{

6 | Page

while (_stack[_toper] != '(')


{
_top++;
_post[_top] = _stack[_toper];
_stack[_toper] = '\0';
_toper--;
}
_stack[_toper] = '\0';
_toper--;
}
catch (Exception)
{
_flag = 0;
}

}
/*method for checking operator precedence*/
int Checkprec(char x)
{
switch (x)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '(':
return 0;
default:
return 0;
}
}

Illustration of the solution:


This program evaluates arithmetic expressions consisting of integer numbers,
the operators +, -, *, and /, and parentheses. A recursive parser is used to
evaluate the expression. This parser is based on the following context-free
grammar:
Expression -> Expression + Term | Expression - Term | Term
Term
-> Term * Factor
| Term / Factor
| Factor
Factor
-> (Expression)
| Number
Number
-> 0|1|2|3|4|5|6|7|8|9
And also this program converts the infix expression i.e. arithmetic expression
to postfix expression. To convert infix expression to postfix expression I used
reversed polish notation method.
This program has four parts and each part contains a class.
- Class Execute is built for starting the program by using main method,
7 | Page

Class InputExpression is built for taking input an expression from


console window and passing that expression to another class, and the
last
Class Sdtforarithmaticexp is built to validate arithmetic expression.
Class InfixToPostfix is built for converting infix expression to postfix
expression. This class will work only when the input expression is
validated and produced result - correct expression by class
Sdtforarithmaticexp.

1st Part:
The class Execute has only one method that is main method to start the
program. An object of class InputExpression is created inside the main
method to enter into the InputExpression class.
2nd Part:
The class InputExpression has only one method names Input. Input method
takes an arithmetic expression from the console window. And passed it to
class Sdtforarithmaticexp by creating object of this class.
3rd Part:
The class Sdtforarithmaticexp has five methods names ScanString,
EvaluateExpression, EvaluateTerm, EvaluateFactor and Input. Various types of
arrays and global variables has to be declared for working on this like char[]
number,
int[]
terminal,
int[]
terminal_value,
terminal_position,
number_position, MAXCHARACTERS, MAXTERMINALS, MAXDIGITS etc.
Initial method is Input method which takes an arithmetic expression from
InputExpression class by argument. Then, it passes the inputstring to the
ScanString method to make a list for all token in the input string and checking
whether all input character is right or wrong. If right then puts it into the list
table otherwise throw an error e.g. invalid character then exit from program.
To make the list of token a while loop is used, this loop will work until finds all
the valid tokens.
When complete the task for making list of token, then the list is passed into
the Evaluate Expression table. As mentioned earlier, to evaluate that
expression a context free grammar is used. To evaluate this expression,
EvaluateTerm and EvaluateFactor methods help the EvaluateExpression
method. Here, first finds the factor, then term and finally the expression. In
the expression, + and are evaluated, in the EvaluateTerm method, * and /
are evaluated. If the expression with parenthesis encountered then
EvaluateExpression is executed. For validating the expression, right to left
recursion method is used in this program. All the token is identified by the
8 | Page

terminal_position. If terminal_position is zero then output will be correct


expression otherwise error will encountered e.g. sorry! Syntax.
4th Part:
This part will work only when the input expression is validated by the class
Sdtforarithmaticexp and produced result that expression is right otherwise
this program will generate an error with Syntax error.
.At first we push ( onto the stack[], and then we add ) to the end of the
expression in[strlen]= ). Scan the _expstring[] by using for loop until the
last position i.e. ). The switch statement uses to check whether each
character is operator or operand, if the operand is encountered then it push
to post[] using Insertpostfix() method. And if the operator is encountered then
it push onto the stack[] using Insertstack() method.
The operator and two operands are popped out from the stack[] when an
operator is encountered that has the low precedence than the top element of
stack[] and added to post[]. If the ) is encountered then repeatedly popped
out the elements from the stack[] and added to post[] until the ( is
encountered.
Finally, all the elements in the post[] and the result after evaluating the
expression is printed on console window.

Input & Output:

Fig: Output Correct Expression


Fig: Output Sorry! Syntax Error

Conclusion:
It was too difficult to build the program using CFG. But the knowledge of the
compiler makes me easier to build this program more efficiently. Without the
concept of the compiler I think it would be quite tough for me to build it. Now
I realize that, the study about the compiler helps us to be a good
programmer.
9 | Page

Anda mungkin juga menyukai