| | |
Console calculator Part 1 : The Scanner
Please support our C# advertiser: Intel Parallel Studio Home
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.
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.
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("+-------------------------------------------+"); } } }
Similar Threads
- CLR Console application vs Win32 Console application (C++)
- simple calculator using a scanner (re2c) and a parser generator (lemon) (C)
- Scanner help (USB Devices and other Peripherals)
- Connecting to a scanner (Java)
- Scanner not working (USB Devices and other Peripherals)
| Thread Tools | Search this Thread |
.net access algorithm angle array barchart bitmap box broadcast c# capturing check checkbox client combobox control conversion convert csharp custom database datagrid datagridview dataset datetime dbconnection degrees delegate design development disappear draganddrop drawing encryption enum event excel file firefox form format forms function gdi+ httpwebrequest image index input install java label leak libraries list listbox mandelbrot math monodevelop mouseclick msword mysql operator path pause photoshop picturebox pixelinversion post programming radians regex remote remoting richtextbox round server sleep socket sql statistics stream string table tcpclientchannel text textbox thread time timer update usercontrol validation virtualization visualbasic visualstudio webbrowser windows winforms wpf xml



