This is a series of 3 code snippets which together form a completly working "calculator".
I used a console application in VS C# 2008, but 2005 should cause no problems.
To start with : here you have the code for a scanner class.
A scanner reads the inputline and tries to get some meaningfull words(sometimes called tokens) from it. It then passes that information to a parser.
Console calculator Part 1 : The Scanner
sknake commented: nice :) I missed this snippet of yours somehow +6
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleCalculator
{
class Scanner
{
/// <summary>
/// Scanner class, main routine here is get_token.
/// get_token returns the next token_value to the parser,
/// and sets some variables. It is up to the parser to decide
/// what to do next.
/// </summary>
public enum token_value
{
NAME, NUMBER, END, LIST, HELP, SQRT,
PLUS = '+', MINUS = '-',
MUL = '*', DIV = '/',
PRINT = ';', ASSIGN = '=',
LPAREN = '(', RPAREN = ')',
};
public token_value curr_tok; //current token value found
public double number_value; //if the token was a number the value is held here
public string name_string; //if the token was a variable name, the name can be found here
private char[] StringToParse; //the "inputstream"
private int charpos = 0; //position of the next character to read from the inputstream
private StringBuilder numberSB = new StringBuilder();
private StringBuilder nameSB = new StringBuilder();
/// <summary>
/// Two generic Dictionary's that use hashing to store string keys and values for
/// variables, commands and reserved words.
/// SymbolTable is public, the parser likes this table too
/// </summary>
public Dictionary<string, double> SymbolTable = new Dictionary<string, double>();
private Dictionary<string, token_value> ReservedWords = new Dictionary<string, token_value>();
/// <summary>
/// Scanner default custom constructor, defines a small set of reseved words,
/// used to give special commands to the calculator.
/// </summary>
public Scanner()
{
ReservedWords.Add("END", token_value.END); //Quit the application.
ReservedWords.Add("LIST", token_value.LIST);//Show a list of all variables in the calculator.
ReservedWords.Add("?", token_value.HELP); //Display help info
ReservedWords.Add("SQRT", token_value.SQRT); //Function to take the square root
}
//property to pass the inputline to the scanner
//---------------------------------------------
public string InputLine
{
set
{
string line = value + "\n";
StringToParse = line.ToCharArray();
}
}
//for functions we must first find a left parentesis
//--------------------------------------------------
public bool FindLeftParentesis()
{
char ch;
try
{
do
{
ch = GetChar();
}
while (!ch.Equals('('));
return true;
}
catch
{
Error("( expected"); return false;
}
}
//find a character in the "inputstream"
//-------------------------------------
private char GetChar()
{
char ch = StringToParse[charpos];
charpos++;
return ch;
}
public void PutBackChar()
{
charpos--;
}
public void InitScan()
{
charpos = 0;
number_value = 0.0;
name_string = "";
}
public void Error(string message)
{
//minor error handling, but sufficient for the moment
Console.ForegroundColor = ConsoleColor.Black;
Console.BackgroundColor = ConsoleColor.Cyan;
Console.WriteLine(message);
Console.ResetColor();
}
/// <summary>
/// Main function of the scanner returns the current token and
/// sets the variables name_string and number_value when appropriate.
/// </summary>
/// <returns></returns>
public token_value get_token()
{
char ch;
do //skip whitespace except '\n'
{
ch = GetChar();
}
while (ch != '\n' && char.IsWhiteSpace(ch));
switch (ch)
{
case ';': case '\n':
curr_tok = token_value.PRINT;
return curr_tok;
case '*':
case '/':
case '+':
case '-':
case '(':
case ')':
case '=':
curr_tok = (token_value)(ch);
return curr_tok;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
case ',':
if (ch == '.') ch = ',';
numberSB.Append(ch);
ch = GetChar();
if (ch == '.') ch = ',';
while (char.IsDigit(ch) || ch == ',')
{
numberSB.Append(ch);
ch = GetChar();
}
PutBackChar();
try
{
number_value = Convert.ToDouble(numberSB.ToString());
numberSB.Remove(0, numberSB.Length);
}
catch
{
Error("Fout in formaat van getal.");
}
return token_value.NUMBER;
default:
if (char.IsLetter(ch) | ch.Equals('?'))
{
nameSB.Append(ch);
ch = GetChar();
while (char.IsLetterOrDigit(ch))
{
nameSB.Append(ch);
ch = GetChar();
}
PutBackChar();
name_string = nameSB.ToString();
nameSB.Remove(0, nameSB.Length);
if (ReservedWords.TryGetValue(name_string.ToUpper(), out curr_tok)) return curr_tok;
return token_value.NAME;
}
Error("Bad token.");
return token_value.PRINT;
}
} //end get_token
//print a list of all the variables defined in the symboltable
//------------------------------------------------------------
public void ListVars()
{
Console.WriteLine("+-------------------------------------------+");
Console.WriteLine("| List of variables : |");
Console.WriteLine("+-------------------------------------------+");
Console.WriteLine();
foreach (KeyValuePair<string, double> kvp in SymbolTable)
{
Console.WriteLine("Var = {0} \t = {1}", kvp.Key, kvp.Value);
} //yeah, generics is something to get used to
Console.WriteLine("+-------------------------------------------+");
}
}
}
ddanbe 2,724 Professional Procrastinator Featured Poster
pradeep9601 0 Newbie Poster
ddanbe 2,724 Professional Procrastinator Featured Poster
pradeep9601 0 Newbie Poster
ddanbe 2,724 Professional Procrastinator Featured Poster
pradeep9601 0 Newbie Poster
ddanbe 2,724 Professional Procrastinator Featured Poster
pradeep9601 0 Newbie Poster
ddanbe 2,724 Professional Procrastinator Featured Poster
hafsa ayaz 0 Newbie Poster
ddanbe 2,724 Professional Procrastinator Featured Poster
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.