Click here to Skip to main content
15,885,032 members
Articles / Programming Languages / C#

A Simple Compiler for the Common Language Runtime

Rate me:
Please Sign up or sign in to vote.
4.89/5 (86 votes)
11 May 20039 min read 295K   5.1K   190  
An end-to-end example of a bottom up LALR(1) compiler for a fictitious language targeting the Common Language Runtime
/*
Sharp Compiler
Copyright (C) 2003  Michael Bebenita

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections;

namespace Core
{
	public class SyntaxStack
	{
		private Stack m_Stack = new Stack(100);
		public Stack Stack{get{return m_Stack;}}
		public object Pop(){return m_Stack.Pop();}
		public object Peek(){return m_Stack.Peek();}
		public void Push(object value){m_Stack.Push(value);}
		public void Pop(int count)
		{
			while(count-- > 0)
				m_Stack.Pop();
		}

		/// <summary>
		/// Remove item at specified depth off the stack. 0 means top of stack.
		/// </summary>
		public void Remove(int depth)
		{
			Stack temp = new Stack();
			for(;depth > 0;depth --)
				temp.Push(m_Stack.Pop());
			m_Stack.Pop();
			while(temp.Count > 0)
				m_Stack.Push(temp.Pop());
		}

		public string PopString(){return (string)m_Stack.Pop();}
		public Type PopType(){return (Type)m_Stack.Pop();}
		public Body PopBody(){return (Body)m_Stack.Pop();}
		public Expression PopExpression(){return (Expression)m_Stack.Pop();}

		public CollectionBase PeekCollection(){return (CollectionBase)m_Stack.Peek();}

		public Statement PopStatement(){return (Statement)m_Stack.Pop();}
		public Assignment PopAssignment(){return (Assignment)m_Stack.Pop();}
	}


	public enum PassMethod
	{
		ByValue,
		ByReference
	}

	public enum VariableType
	{
		Primitive,
		PrimitiveArray,
		Structure,
		StructureArray
	}

	public enum PrimitiveType
	{
		Boolean,
		Integer,
		Real,
		Character,
		Void
	}

	public enum BinaryOperatorType
	{
		None,
		Add,
		Subtract,
		Multiply,
		Divide,
		Modulo,
		GreaterThen,
		LessThen,
		GraterOrEqualTo,
		LessOrEqualTo,
		Equal,
		NotEqual,
		And,
		Or
	}

	public enum UnaryOperatorType
	{
		None,
		Positive,
		Negative,
		Not,
		Indexer
	}


	/// <summary>
	/// Describes a type.
	/// </summary>
	public class Type
	{
		/// <summary>
		/// Name of type, generally name of structure if VariableType is Structure.
		/// </summary>
		public string Name;
		/// <summary>
		/// Variable type.
		/// </summary>
		public VariableType VariableType = VariableType.Primitive;
		/// <summary>
		/// Primitive type if VariableType is Primitive.
		/// </summary>
		public PrimitiveType PrimitiveType = PrimitiveType.Void;

		public bool IsRef = false;

		/// <summary>
		/// Create a primitive type.
		/// </summary>
		/// <param name="primitiveType"></param>
		public Type(PrimitiveType primitiveType)
		{
			VariableType = VariableType.Primitive;
			PrimitiveType = primitiveType;
		}

		/// <summary>
		/// Create a structure type.
		/// </summary>
		/// <param name="name"></param>
		public Type(string name)
		{
			VariableType = VariableType.Structure;
			Name = name;
		}

		/// <summary>
		/// Creates a .NET system type from type.
		/// </summary>
		/// <returns></returns>
		public System.Type ToSystemType()
		{
			if(!IsRef)
			{
				if(VariableType == VariableType.Primitive)
				{
					if(PrimitiveType == PrimitiveType.Integer)
						return typeof(int);
					else if(PrimitiveType == PrimitiveType.Boolean)
						return typeof(bool);
					else if(PrimitiveType == PrimitiveType.Character)
						return typeof(char);
					else if(PrimitiveType == PrimitiveType.Real)
						return typeof(float);
					else if(PrimitiveType == PrimitiveType.Void)
						return typeof(void);
				}
				else if(VariableType == VariableType.PrimitiveArray)
				{
					if(PrimitiveType == PrimitiveType.Integer)
						return typeof(int []);
					else if(PrimitiveType == PrimitiveType.Boolean)
						return typeof(bool []);
					else if(PrimitiveType == PrimitiveType.Character)
						return typeof(char []);
					else if(PrimitiveType == PrimitiveType.Real)
						return typeof(float []);
				}
			}
			else
			{
				if(VariableType == VariableType.Primitive)
				{
					if(PrimitiveType == PrimitiveType.Integer)
						return System.Type.GetType("System.Int32&");
					else
						return typeof(void);
				}
				else if(VariableType == VariableType.PrimitiveArray)
				{
					if(PrimitiveType == PrimitiveType.Integer)
						return System.Type.GetType("System.Int32[]&");
					else
						return typeof(void);
				}
			}
			return null;
		}

		private Type() {}	// Hidden default constructor.

		/// <summary>
		/// Create a primitive array type from a non array type.
		/// </summary>
		public static Type CreateArrayFromType(Type type)
		{
			if(type.VariableType == VariableType.Primitive)
				type.VariableType = VariableType.PrimitiveArray;
			else if(type.VariableType == VariableType.Structure)
				type.VariableType = VariableType.StructureArray;
			return type;
		}

		/// <summary>
		/// Create a primitive array type.
		/// </summary>
		public static Type CreateArrayType(PrimitiveType primitiveType)
		{
			Type newType = new Type();
			newType.VariableType = VariableType.PrimitiveArray;
			newType.PrimitiveType = primitiveType;
			return newType;
		}

		/// <summary>
		/// Create a structure array type.
		/// </summary>
		public static Type CreateArrayType(string name)
		{
			Type newType = new Type();
			newType.VariableType = VariableType.StructureArray;
			newType.Name = name;
			return newType;
		}

	}


	public enum LiteralType
	{
		Boolean,
		Integer,
		Real,
		Character,
		String
	}

	/// <summary>
	/// Describes a literal found in text
	/// </summary>
	public class Literal : Expression
	{
		/// <summary>
		/// Textual value of the literal, string and character literals include quotes.
		/// </summary>
		public string Value;

		/// <summary>
		/// Type of literal.
		/// </summary>
		public LiteralType LiteralType;

		/// <summary>
		/// Create a literal object.
		/// </summary>
		/// <param name="value">Value of the literal.</param>
		/// <param name="literalType">Literal type.</param>
		public Literal(string value, LiteralType literalType)
		{
			Value = value;	LiteralType = literalType;
		}
	}

	/// <summary>
	/// Describes a compilation unit.
	/// </summary>
	public class Module
	{
		/// <summary>
		/// Name of module.
		/// </summary>
		public string Name;

		/// <summary>
		/// Module body.
		/// </summary>
		public Body Body;

		/// <summary>
		/// Create a module object.
		/// </summary>
		public Module(Body body, string name)
		{
			Body = body;	Name = name;
		}

	}

	/// <summary>
	/// Describes a code body.
	/// </summary>
	public class Body
	{
		public FunctionCollection Functions	= null;
		public StructureCollection Structures = null;
		public StatementCollection Statements = null;

		public Compilation.SymbolTable SymbolTable = null;

		/// <summary>
		/// Create a body from a collection of statements. 
		/// Functions, variables, structures and regular statements will be separated.
		/// </summary>
		public Body(StatementCollection statements)
		{			
			if(statements == null)
				return;

			Functions = new FunctionCollection();
			Structures = new StructureCollection();
			Statements = new StatementCollection();

			foreach(Statement statement in statements)
			{
				if(statement.GetType() == typeof(Function))
					Functions.Add((Function)statement);
				//else if(statement.GetType() == typeof(Variable))
				//	Variables.Add((Variable)statement);
				else if(statement.GetType() == typeof(Structure))
					Structures.Add((Structure)statement);
				else 
					Statements.Add(statement);
			}
		}
	}

	/// <summary>
	/// Describes a function.
	/// </summary>
	public class Function : Statement
	{
		/// <summary>
		/// Function name.
		/// </summary>
		public string Name;
		/// <summary>
		/// Function body.
		/// </summary>
		public Body Body;
		/// <summary>
		/// Function type.
		/// </summary>
		public Type Type;
		/// <summary>
		/// Function parameters.
		/// </summary>
		public ParameterCollection Parameters;

		/// <summary>
		/// IL method builder.
		/// </summary>
		public MethodBuilder Builder;

		/// <summary>
		/// Creates a function object.
		/// </summary>
		public Function(Body body, ParameterCollection parameters, string name, Type type)
		{
			Body = body;	Parameters = parameters;	Name = name;	Type = type;
		}
	}

	/// <summary>
	/// Describes a function call statement.
	/// </summary>
	public class CallStatement : Statement
	{
		/// <summary>
		/// Function to call.
		/// </summary>
		public string Name;

		/// <summary>
		/// Function arguments to pass.
		/// </summary>
		public ArgumentCollection Arguments;

		/// <summary>
		/// Creates a function call object.
		/// </summary>
		public CallStatement(ArgumentCollection arguments, string name)
		{
			Arguments = arguments;	Name = name;
		}
	}

	/// <summary>
	/// Describes a function call.
	/// </summary>
	public class Call : Expression
	{
		/// <summary>
		/// Function to call.
		/// </summary>
		public string Name;

		/// <summary>
		/// Function arguments to pass.
		/// </summary>
		public ArgumentCollection Arguments;

		/// <summary>
		/// Creates a function call object.
		/// </summary>
		public Call(ArgumentCollection arguments, string name)
		{
			Arguments = arguments;	Name = name;
		}
	}

	/// <summary>
	/// Describes a structure.
	/// </summary>
	public class Structure : Statement
	{
		/// <summary>
		/// Structure name.
		/// </summary>
		public string Name;

		/// <summary>
		/// Structure variables.
		/// </summary>
		public VariableCollection Variables = null;

		/// <summary>
		/// Create a structure object.
		/// </summary>
		public Structure(VariableCollection variables, string name)
		{
			Variables = variables;	Name = name;
		}

	}

	/// <summary>
	/// Describes a variable.
	/// </summary>
	public class Variable : Statement
	{
		/// <summary>
		/// Variable name.
		/// </summary>
		public string Name;
		/// <summary>
		/// Variable type.
		/// </summary>
		public Type Type;

		/// <summary>
		/// Variable initial value;
		/// </summary>
		public object Value;

		/// <summary>
		/// Create a variable object.
		/// </summary>
		public Variable(object value, string name, Type type)
		{
			Name = name;	Type = type;	Value = value;
		}
	}

	/// <summary>
	/// Describes a parameter.
	/// </summary>
	public class Parameter
	{
		/// <summary>
		/// Parameter name.
		/// </summary>
		public string Name;
		/// <summary>
		/// Parameter type.
		/// </summary>
		public Type Type;
		/// <summary>
		/// Parameter pass method.
		/// </summary>
		public PassMethod PassMethod = PassMethod.ByValue;

		/// <summary>
		/// Create parameter object.
		/// </summary>
		public Parameter(string name, Type type, PassMethod passMethod)
		{
			Name = name;	Type = type;	PassMethod = passMethod;
		}
	}

	/// <summary>
	/// Describes an argument.
	/// </summary>
	public class Argument
	{
		/// <summary>
		/// Argument expression.
		/// </summary>
		public Expression Value;

		/// <summary>
		/// Argument pass method.
		/// </summary>
		public PassMethod PassMethod = PassMethod.ByValue;

		/// <summary>
		/// Create argument object.
		/// </summary>
		public Argument(Expression value, PassMethod passMethod)
		{
			Value = value;	PassMethod = passMethod;
		}
	}

	/// <summary>
	/// Describes a statement.
	/// </summary>
	public class Statement
	{

	}

	public enum ElementType
	{
		Collection,
		Expression
	}

	/// <summary>
	/// Describes an array or structure initialization element.
	/// </summary>
	public class Element
	{
		public ElementType ElementType = ElementType.Expression;
		public ElementCollection Elements = null;
		public Expression Expression = null;

		/// <summary>
		/// Creates an element collection element object.
		/// </summary>
		public Element(ElementCollection elements)
		{
			ElementType = ElementType.Collection;
			Elements = elements;
		}

		/// <summary>
		/// Creates a expression element object.
		/// </summary>
		public Element(Expression expression)
		{
			ElementType = ElementType.Expression;
			Expression = expression;
		}
	}

	public abstract class Expression
	{
		public Type Type;
	}

	public class BinaryExpression : Expression
	{
		public Expression Right = null;
		public Expression Left = null;
		public BinaryOperatorType BinaryOperatorType = BinaryOperatorType.None;

		public BinaryExpression(Expression right, Expression left, BinaryOperatorType binaryOperatorType)
		{
			Right = right;	Left = left;	BinaryOperatorType = binaryOperatorType;
		}
	}

	public class UnaryExpression : Expression
	{
		public Expression Value = null;
		public Expression Indexer = null;
		public UnaryOperatorType UnaryOperatorType = UnaryOperatorType.None;

		public UnaryExpression(Expression indexer, Expression value, UnaryOperatorType unaryOperatorType)
		{
			Value = value;	Indexer = indexer;	UnaryOperatorType = unaryOperatorType;
		}
	}

	public class Name : Expression
	{
		public string Value;
		public Name(string value)
		{
			Value = value;
		}
	}

	/// <summary>
	/// Describes a return statement.
	/// </summary>
	public class Return : Statement
	{
		/// <summary>
		/// Return value;
		/// </summary>
		public Expression Value;
		/// <summary>
		/// Create return object.
		/// </summary>
		/// <param name="value"></param>
		public Return(Expression value)
		{
			Value = value;
		}
	}

	public class If : Statement
	{
		public Expression Condition = null;
		public Body IfBody = null;
		public Body ElseBody = null;

		public If(Body elseBody, Body ifBody, Expression condition)
		{
			ElseBody = elseBody;	IfBody = ifBody;	Condition = condition;
		}
	}

	public class While : Statement
	{
		public Expression Condition = null;
		public Body Body = null;

		public While(Body body, Expression condition)
		{
			Body = body;
			Condition = condition;
		}
	}

	public class Do : Statement
	{
		public Expression Condition = null;
		public Body Body = null;

		public Do(Expression condition,Body body)
		{
			Body = body;
			Condition = condition;
		}
	}

	public class For : Statement
	{
		public Assignment Initializer = null;
		public Expression Condition = null;
		public Assignment Counter = null;
		public Body Body = null;

		public For(Body body, Assignment counter, Expression condition, Assignment initializer)
		{
			Body = body;	Counter = counter;	Condition = condition;	Initializer = initializer;
		}
	}

	public class Assignment : Statement
	{
		public string Name;
		public Expression Value;
		public Expression Index;
		public Assignment(Expression value, Expression index, string name)
		{
			Value = value;	Name = name;	Index = index;
		}
	}

	public class Semantics
	{
		public static void Apply(Production production, SyntaxStack stack)
		{
			switch(production.m_ID)
			{
				case 0: // <Literal> ::= boolean_literal
					// Create boolean literal object.
					stack.Push(new Literal(stack.PopString(),LiteralType.Boolean));
					break;
				case 1: // <Literal> ::= integer_literal
					// Create integer literal object.
					stack.Push(new Literal(stack.PopString(),LiteralType.Integer));
					break;
				case 2: // <Literal> ::= real_literal
					// Create real literal object.
					stack.Push(new Literal(stack.PopString(),LiteralType.Real));
					break;
				case 3: // <Literal> ::= character_literal
					// Create character literal object.
					stack.Push(new Literal(stack.PopString(),LiteralType.Character));
					break;
				case 4: // <Literal> ::= string_literal
					// Create string literal object.
					stack.Push(new Literal(stack.PopString(),LiteralType.String));
					break;
				case 5: // <Type> ::= <Structure_Type>
					// !!! DO NOTHING !!!
					break;
				case 6: // <Type> ::= <Primitive_Type>
					// !!! DO NOTHING !!!
					break;
				case 7: // <Type> ::= <Array_Type>
					// !!! DO NOTHING !!!
					break;
				case 8: // <Structure_Type> ::= identifier
					// Create structure type object.
					stack.Push(new Type(stack.PopString()));
					break;
				case 9: // <Primitive_Type> ::= bool
					// Create a boolean type object.
					stack.Pop(1);
					stack.Push(new Type(PrimitiveType.Boolean));
					break;
				case 10: // <Primitive_Type> ::= int
					// Create an integer type object.
					stack.Pop(1);
					stack.Push(new Type(PrimitiveType.Integer));
					break;
				case 11: // <Primitive_Type> ::= real
					// Create an real type object.
					stack.Pop(1);
					stack.Push(new Type(PrimitiveType.Real));
					break;
				case 12: // <Primitive_Type> ::= char
					// Create an character type object.
					stack.Pop(1);
					stack.Push(new Type(PrimitiveType.Character));
					break;
				case 13: // <Primitive_Type> ::= void
					// Create an void type object.
					stack.Pop(1);
					stack.Push(new Type(PrimitiveType.Void));
					break;
				case 14: // <Array_Type> ::= <Structure_Type> '[' ']'
					// Create a structure array type.
					stack.Pop(2);
					stack.Push(Type.CreateArrayFromType(stack.PopType()));
					break;
				case 15: // <Array_Type> ::= <Primitive_Type> '[' ']'
					// Create a primitive array type.
					stack.Pop(2);
					stack.Push(Type.CreateArrayFromType(stack.PopType()));
					break;
				case 16: // <Module> ::= module identifier <Body>
					// Create a module object.
					stack.Remove(2);
					stack.Push(new Module(stack.PopBody(),stack.PopString()));
					break;
				case 17: // <Body> ::= '{' <Statements> '}'
					// Create a body object.
					stack.Pop(1);
					Body body = new Body((StatementCollection)stack.Pop());
					stack.Pop(1);
					stack.Push(body);
					break;
				case 18: // <Body> ::= '{' '}'
					// Create a null body object.
					stack.Pop(2);
					stack.Push(new Body(null));
					break;
				case 19: // <Name> ::= identifier
					// !!! DO NOTHING !!!
					break;
				case 20: // <Name> ::= <Name> . identifier
					// Append name section to top of stack.
					string identifer = stack.PopString();
					stack.Pop(1);
					string name = stack.PopString();
					stack.Push(name + "." + identifer);
					break;
				case 21: // <Variable_Declarations> ::= <Variable_Declaration>
					// Create a variable collection containing the variable on top of the stack.
					stack.Push(new VariableCollection((Variable)stack.Pop()));
					break;
				case 22: // <Variable_Declarations> ::= <Variable_Declarations> <Variable_Declaration>
					// Add the variable on top of the stack to the variable collection.
					Variable variable = (Variable)stack.Pop();
					((VariableCollection)stack.Peek()).Add(variable);
					break;
				case 23: // <Variable_Declaration> ::= <Type> identifier ;
					// Create a variable object with a null value.
					stack.Pop(1);
					stack.Push(new Variable(null,stack.PopString(),stack.PopType()));
					break;
				case 24: // <Variable_Declaration> ::= <Type> identifier = <Expression> ;
					// Create a variable object with an expression value.
					stack.Pop(1);
					stack.Remove(1);
					stack.Push(new Variable(stack.PopExpression(), stack.PopString(),stack.PopType()));
					break;
				case 25: // <Variable_Declaration> ::= <Type> identifier = new '[' <Expression> ']' ;
					// Create a variable object with an expression value.
					stack.Pop(2);	stack.Remove(1);	stack.Remove(1);	stack.Remove(1);
					stack.Push(new Variable(stack.PopExpression(), stack.PopString(),stack.PopType()));
					break;
				case 26: // <Variable_Declaration> ::= <Type> identifier = '{' <Elements> '}' ;
					// Create a variable object with an element collection value.
					stack.Pop(2);	stack.Remove(1);	stack.Remove(1);
					stack.Push(new Variable(stack.Pop(), stack.PopString(),stack.PopType()));
					break;
				case 27: // <Elements> ::= <Element>
					// Create an element collection containing the element on top of the stack.
					stack.Push(new ElementCollection((Element)stack.Pop()));
					break;
				case 28: // <Elements> ::= <Elements> , <Element>
					// Add the element on top of the stack to the current element collection.
					Element element = (Element)stack.Pop();
					stack.Pop(1);
					((ElementCollection)stack.Peek()).Add(element);
					break;
				case 29: // <Element> ::= <Expression>
					// Create a new element object.
					stack.Push(new Element(stack.PopExpression()));
					break;
				case 30: // <Element> ::= '{' <Elements> '}'
					// Create a new element object with elements inside of it.
					stack.Pop(1);	stack.Remove(1);
					stack.Push(new Element((ElementCollection)stack.Pop()));
					break;
				case 31: // <Function_Declaration> ::= <Type> identifier '(' ')' <Body>
					// Create a function object.
					stack.Remove(1);	stack.Remove(1);
					stack.Push(new Function(stack.PopBody(),null,stack.PopString(),stack.PopType()));
					break;
				case 32: // <Function_Declaration> ::= <Type> identifier '(' <Parameters> ')' <Body>
					// Create a function object.
					stack.Remove(1);	stack.Remove(2);
					stack.Push(new Function(stack.PopBody(),(ParameterCollection)stack.Pop(),stack.PopString(),stack.PopType()));
					break;
				case 33: // <Parameters> ::= <Parameter>
					// Create a parameter collection containing the parameter on top of the stack.
					stack.Push(new ParameterCollection((Parameter)stack.Pop()));
					break;
				case 34: // <Parameters> ::= <Parameters> , <Parameter>
					// Add parameter to parameter collection.
					Parameter parameter = (Parameter)stack.Pop();
					stack.Pop(1);
					((ParameterCollection)stack.Peek()).Add(parameter);
					break;
				case 35: // <Parameter> ::= <Type> identifier
					// Create a parameter object.
					stack.Push(new Parameter(stack.PopString(),stack.PopType(),PassMethod.ByValue));
					break;
				case 36: // <Parameter> ::= ref <Type> identifier
					// Create a parameter object.
					stack.Remove(2);
					stack.Push(new Parameter(stack.PopString(),stack.PopType(),PassMethod.ByReference));
					((Parameter)stack.Peek()).Type.IsRef = true;
					break;
				case 37: // <Function_Call> ::= <Name> '(' ')'
					// Create a function call object.
					stack.Pop(2);
					stack.Push(new Call(null,stack.PopString()));
					break;
				case 38: // <Function_Call> ::= <Name> '(' <Arguments> ')'
					// Create a function call object.
					stack.Pop(1);	stack.Remove(1);
					stack.Push(new Call((ArgumentCollection)stack.Pop(),stack.PopString()));
					break;
				case 39: // <Arguments> ::= <Argument>
					// Create an argument collection containing the argument on top of stack.
					stack.Push(new ArgumentCollection((Argument)stack.Pop()));
					break;
				case 40: // <Arguments> ::= <Arguments> , <Argument>
					// Add argument to argument collection.
					Argument argument = (Argument)stack.Pop();
					stack.Pop(1);
					((ArgumentCollection)stack.Peek()).Add(argument);
					break;
				case 41: // <Argument> ::= <Expression>
					// Create argument object.
					stack.Push(new Argument(stack.PopExpression(),PassMethod.ByValue));
					break;
				case 42: // <Argument> ::= ref <Expression>
					// Create argument object.
					stack.Remove(1);
					stack.Push(new Argument(stack.PopExpression(),PassMethod.ByReference));
					break;
				case 43: // <Structure_Declaration> ::= struct identifier '{' <Variable_Declarations> '}'
					// Create structure object.
					stack.Pop(1);	stack.Remove(1);	stack.Remove(2);
					stack.Push(new Structure((VariableCollection)stack.Pop(),stack.PopString()));
					break;
				case 44: // <Structure_Declaration> ::= struct identifier '{' '}'
					// Create structure object.
					stack.Pop(2);	stack.Remove(1);
					stack.Push(new Structure(null,stack.PopString()));
					break;
				case 45: // <Statements> ::= <Statement>
					// Create statement collection containing statement on stack.
					stack.Push(new StatementCollection(stack.PopStatement()));
					break;
				case 46: // <Statements> ::= <Statements> <Statement>
					// Add current statement to collection.
					Statement statement = stack.PopStatement();
					((StatementCollection)stack.Peek()).Add(statement);
					break;
				case 47: // <Statement> ::= <Variable_Declaration>
					// !!! DO NOTHING !!!
					break;
				case 48: // <Statement> ::= <Function_Declaration>
					// !!! DO NOTHING !!!
					break;
				case 49: // <Statement> ::= <Structure_Declaration>
					// !!! DO NOTHING !!!
					break;
				case 50: // <Statement> ::= <Function_Call> ;
					// Remove ';'
					stack.Pop(1);
					Call call = (Call)stack.Pop();
					stack.Push(new CallStatement(call.Arguments,call.Name));
					break;
				case 51: // <Statement> ::= <Assignment> ;
					// Remove ';'
					stack.Pop(1);
					break;
				case 52: // <Statement> ::= return <Expression> ;
					// Create return object.
					stack.Pop(1);	stack.Remove(1);
					stack.Push(new Return(stack.PopExpression()));
					break;
				case 53: // <Statement> ::= return ;
					// Create return object.
					stack.Pop(2);
					stack.Push(new Return(null));
					break;
				case 54: // <Statement> ::= if '(' <Expression> ')' <Body>
					// Create if statement.
					stack.Remove(1);	stack.Remove(2);	stack.Remove(2);
					stack.Push(new If(null,stack.PopBody(),stack.PopExpression()));
					break;
				case 55: // <Statement> ::= if '(' <Expression> ')' <Body> else <Body>
					// Create if statement.
					stack.Remove(1);	stack.Remove(2);	stack.Remove(3);	stack.Remove(3);
					stack.Push(new If(stack.PopBody(),stack.PopBody(),stack.PopExpression()));
					break;
				case 56: // <Statement> ::= while '(' <Expression> ')' <Body>
					// Create while statement.
					stack.Remove(1);	stack.Remove(2);	stack.Remove(2);
					stack.Push(new While(stack.PopBody(),stack.PopExpression()));
					break;
				case 57: // <Statement> ::= do <Body> while '(' <Expression> ')'
					/// Create do statement.
					stack.Pop(1);	stack.Remove(1);	stack.Remove(1);	stack.Remove(2);
					stack.Push(new Do(stack.PopExpression(),stack.PopBody()));
					break;
				case 58: // <Statement> ::= for '(' <Assignment> ; <Expression> ; <Assignment> ')' <Body>
					// Create for statement.
					stack.Remove(1);	stack.Remove(2);	stack.Remove(3);	stack.Remove(4);	stack.Remove(4);
					stack.Push(new For(stack.PopBody(),stack.PopAssignment(),stack.PopExpression(),stack.PopAssignment()));
					break;
				case 59: // <Assignment> ::= set <Name> = <Expression>
					// Create assignment statement.
					stack.Remove(1);
					stack.Remove(2);
					stack.Push(new Assignment(stack.PopExpression(),null,stack.PopString()));
					break;
				case 60: // <Assignment> ::= set <Name> [ <Expression> ] = <Expression>
					// Create assignment statement.
					stack.Remove(1);
					stack.Remove(1);
					stack.Remove(2);
					stack.Remove(3);
					stack.Push(new Assignment(stack.PopExpression(),stack.PopExpression(),stack.PopString()));
					break;
				case 61: // <Assignment> ::= set <Name> '++'
					// TO DO:
					break;
				case 62: // <Assignment> ::= set <Name> '--'
					// TO DO:
					break;
				case 63: // <Expression> ::= <Expression_Term>
					// !!! DO NOTHING !!!
					break;
				case 64: // <Expression> ::= <Expression> '+' <Expression_Term>
					// Create binary expression.
					stack.Remove(1);
					stack.Push(new BinaryExpression(stack.PopExpression(),stack.PopExpression(),BinaryOperatorType.Add));
					break;
				case 65: // <Expression> ::= <Expression> '-' <Expression_Term>
					// Create binary expression.
					stack.Remove(1);
					stack.Push(new BinaryExpression(stack.PopExpression(),stack.PopExpression(),BinaryOperatorType.Subtract));
					break;
				case 66: // <Expression_Term> ::= <Expression_Factor>
					// !!! DO NOTHING !!!
					break;
				case 67: // <Expression_Term> ::= <Expression_Term> '*' <Expression_Factor>
					// Create binary expression.
					stack.Remove(1);
					stack.Push(new BinaryExpression(stack.PopExpression(),stack.PopExpression(),BinaryOperatorType.Multiply));
					break;
				case 68: // <Expression_Term> ::= <Expression_Term> / <Expression_Factor>
					// Create binary expression.
					stack.Remove(1);
					stack.Push(new BinaryExpression(stack.PopExpression(),stack.PopExpression(),BinaryOperatorType.Divide));
					break;
				case 69: // <Expression_Factor> ::= <Expression_Binary>
					// !!! DO NOTHING !!!
					break;
				case 70: // <Expression_Factor> ::= <Expression_Factor> % <Expression_Binary>
					// Create binary expression.
					stack.Remove(1);
					stack.Push(new BinaryExpression(stack.PopExpression(),stack.PopExpression(),BinaryOperatorType.Modulo));
					break;
				case 71: // <Expression_Factor> ::= <Expression_Factor> '>' <Expression_Binary>
					// Create binary expression.
					stack.Remove(1);
					stack.Push(new BinaryExpression(stack.PopExpression(),stack.PopExpression(),BinaryOperatorType.GreaterThen));
					break;
				case 72: // <Expression_Factor> ::= <Expression_Factor> '<' <Expression_Binary>
					// Create binary expression.
					stack.Remove(1);
					stack.Push(new BinaryExpression(stack.PopExpression(),stack.PopExpression(),BinaryOperatorType.LessThen));
					break;
				case 73: // <Expression_Factor> ::= <Expression_Factor> '>=' <Expression_Binary>
					// Create binary expression.
					stack.Remove(1);
					stack.Push(new BinaryExpression(stack.PopExpression(),stack.PopExpression(),BinaryOperatorType.GraterOrEqualTo));
					break;
				case 74: // <Expression_Factor> ::= <Expression_Factor> '<=' <Expression_Binary>
					// Create binary expression.
					stack.Remove(1);
					stack.Push(new BinaryExpression(stack.PopExpression(),stack.PopExpression(),BinaryOperatorType.LessOrEqualTo));
					break;
				case 75: // <Expression_Factor> ::= <Expression_Factor> == <Expression_Binary>
					// Create binary expression.
					stack.Remove(1);
					stack.Push(new BinaryExpression(stack.PopExpression(),stack.PopExpression(),BinaryOperatorType.Equal));
					break;
				case 76: // <Expression_Factor> ::= <Expression_Factor> '!=' <Expression_Binary>
					// Create binary expression.
					stack.Remove(1);
					stack.Push(new BinaryExpression(stack.PopExpression(),stack.PopExpression(),BinaryOperatorType.NotEqual));
					break;
				case 77: // <Expression_Binary> ::= <Expression_Unary>
					// !!! DO NOTHING !!!
					break;
				case 78: // <Expression_Binary> ::= <Expression_Binary> && <Expression_Unary>
					// Create binary expression.
					stack.Remove(1);
					stack.Push(new BinaryExpression(stack.PopExpression(),stack.PopExpression(),BinaryOperatorType.And));
					break;
				case 79: // <Expression_Binary> ::= <Expression_Binary> '||' <Expression_Unary>
					// Create binary expression.
					stack.Remove(1);
					stack.Push(new BinaryExpression(stack.PopExpression(),stack.PopExpression(),BinaryOperatorType.Or));
					break;
				case 80: // <Expression_Unary> ::= '+' <Expression_Primary>
					// Create unary expression.
					stack.Remove(1);
					stack.Push(new UnaryExpression(null,stack.PopExpression(),UnaryOperatorType.Positive));
					break;
				case 81: // <Expression_Unary> ::= '-' <Expression_Primary>
					// Create unary expression.
					stack.Remove(1);
					stack.Push(new UnaryExpression(null,stack.PopExpression(),UnaryOperatorType.Negative));
					break;
				case 82: // <Expression_Unary> ::= '!' <Expression_Primary>
					// Create unary expression.
					stack.Remove(1);
					stack.Push(new UnaryExpression(null,stack.PopExpression(),UnaryOperatorType.Not));
					break;
				case 83: // <Expression_Unary> ::= <Expression_Primary>
					// !!! DO NOTHING !!!
					break;
				case 84: // <Expression_Unary> ::= <Expression_Primary> '[' <Expression> ']'
					// Create unary expression.
					stack.Pop(1);	stack.Remove(1);
					stack.Push(new UnaryExpression(stack.PopExpression(),stack.PopExpression(),UnaryOperatorType.Indexer));
					break;
				case 85: // <Expression_Primary> ::= <Name>
					// Create name expression.
					stack.Push(new Name(stack.PopString()));
					break;
				case 86: // <Expression_Primary> ::= <Function_Call>
					// !!! DO NOTHING !!!
					break;
				case 87: // <Expression_Primary> ::= <Literal>
					// !!! DO NOTHING !!!
					break;
				case 88:  // <Expression_Primary> ::= '(' <Expression> ')'
					// Remove pharanthesis
					stack.Pop(1);	stack.Remove(1);
					break;

			}
		}
	}

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
Currently a graduate student at UCI.

Comments and Discussions