Overview Chapter 6 Writig a Program Bjare Stroustrup Some thoughts o software developmet The idea of a calculator Usig a grammar Expressio evaluatio Program orgaizatio www.stroustrup.com/programmig 3 Buildig a program 4 Aalysis Refie our uderstadig of the problem Desig Thik of the fial use of our program Create a overall structure for the program Implemetatio Write code Debug Test Go through these stages repeatedly 5 1
Writig a program: Strategy Programmig is also a practical still What is the problem to be solved? Is the problem statemet clear? Is the problem maageable, give the time, skills, ad tools available? Try breakig it ito maageable parts Do we kow of ay tools, libraries, etc. that might help? Yes, eve this early: iostreams, vector, etc. Build a small, limited versio solvig a key part of the problem To brig out problems i our uderstadig, ideas, or tools Possibly chage the details of the problem statemet to make it maageable If that does t work Throw away the first versio ad make aother limited versio Keep doig that util we fid a versio that we re happy with Build a full scale solutio Ideally by usig part of your iitial versio We lear by example Not by just seeig explaatios of priciples Not just by uderstadig programmig laguage rules The more ad the more varied examples the better You wo t get it right the first time You ca t lear to ride a bike from a correspodece course 6 7 Writig a program: Example I ll build a program i stages, makig lot of typical mistakes alog the way Eve experieced programmers make mistakes Lots of mistakes; it s a ecessary part of learig Desigig a good program is geuiely difficult It s ofte faster to let the compiler detect gross mistakes tha to try to get every detail right the first time Cocetrate o the importat desig choices Buildig a simple, icomplete versio allows us to experimet ad get feedback Good programs are grow A simple calculator Give expressios as iput from the keyboard, evaluate them ad write out the resultig value For example Expressio: 2+2 Result: 4 Expressio: 2+2*3 Result: 8 Expressio: 2+3-25/5 Result: 0 Let s refie this a bit more 8 9 2
Pseudo Code A simple calculator A first idea: it mai() variables while (get a lie) aalyze the expressio evaluate the expressio prit the result // pseudo code // what s a lie? // what does that mea? How do we represet 45+5/7 as data? How do we fid 45 + 5 / ad 7 i a iput strig? How do we make sure that 45+5/7 meas 45+(5/7) rather tha (45+5)/7? Should we allow floatig-poit umbers (sure!) Ca we have variables? v=7; m=9; v*m (later) 10 Wait! We are just about to reivet the wheel! Read Chapter 6 for more examples of dead-ed approaches What would the experts do? Computers have bee evaluatig expressios for 50+ years There has to be a solutio! What did the experts do? Readig is good for you Askig more experieced frieds/colleagues ca be far more effective, pleasat, ad time-effective tha sloggig alog o your ow Do t re-ivet the wheel 11 Expressio Grammar This is what the experts usually do write a grammar: Expressio : Term Expressio + Term e.g., 1+2, (1-2)+3, 2*3+1 Expressio - Term Term : Primary Term * Primary e.g., 1*2, (1-2)*3.5 Term / Primary Term % Primary Primary : Number e.g., 1, 3.5 ( Expressio ) e.g., (1+2*3) Number : floatig-poit literal e.g., 3.14, 0.274e1, or 42 as defied for C++ A program is built out of Tokes (e.g., umbers ad operators). 12 A side trip: Grammars What s a grammar? A set of (sytax) rules for expressios. The rules say how to aalyze ( parse ) a expressio. Some rules seem hard-wired ito our brais Example, you kow what this meas: 2*3+4/2 birds fly but fish swim You kow that this is wrog: 2 * + 3 4/2 fly birds fish but swim How ca we teach what we kow to a computer? Why is it right/wrog? How do we kow? 13 3
Grammars Eglish Grammars - expressio 14 15 Grammars - expressio Grammars - expressio 16 17 4
Fuctios for parsig Fuctio Retur Types We eed fuctios to match the grammar rules get() // read characters ad compose tokes // calls ci for iput expressio() // deal with + ad // calls term() ad get() term() // deal with *, /, ad % // calls primary() ad get() primary() // deal with umbers ad paretheses // calls expressio() ad get() Note: each fuctio deals with a specific part of a expressio ad leaves everythig else to other fuctios this radically simplifies each fuctio. Aalogy: a group of people ca deal with a complex problem by each perso hadlig oly problems i his/her ow specialty, leavig the rest for colleagues. 18 What should the parser fuctios retur? How about the result? Toke get_toke(); // read characters ad compose tokes double expressio(); // deal with + ad // retur the sum (or differece) double term(); // deal with *, /, ad % // retur the product (or ) double primary(); // deal with umbers ad paretheses // retur the value What is a Toke? 19 umber 4.5 What is a toke? + Dealig with + ad - We wat to see iput as a stream of tokes We read characters 1 + 4*(4.5-6) (That s 13 characters icl. 2 spaces) 9 tokes i that expressio: 1 + 4 * ( 4.5-6 ) 6 kids of tokes i that expressio: umber + * ( - ) We wat each toke to have two parts A kid ; e.g., umber A value; e.g., 4 We eed a type to represet this Toke idea We ll build that i the ext lecture, but for ow: get_toke() gives us the ext toke from iput t.kid gives us the kid of the toke t.value gives us the value of the toke 20 Expressio: Term Expressio '+' Term Expressio '-' Term // Note: every Expressio starts with a Term double expressio() // read ad evaluate: 1 1+2.5 1+2+3.14 etc. double left = term(); // get the Term while (true) Toke t = get_toke(); // get the ext toke switch (t.kid) // ad do the right thig with it case '+': left += term(); break; case '-': left -= term(); break; default: retur left; // retur the value of the expressio 21 5
Dealig with *, /, ad % Dealig with * ad / double term() // exactly like expressio(), but for *, /, ad % double left = primary(); // get the Primary while (true) Toke t = get_toke(); // get the ext Toke switch (t.kid) case '*': left *= primary(); break; case '/': left /= primary(); break; case '%': left %= primary(); break; default: retur left; // retur the value Oops: does t compile % is t defied for floatig-poit umbers 22 Term : Primary Term * Primary Term / Primary // Note: every Term starts with a Primary double term() // exactly like expressio(), but for *, ad / double left = primary(); // get the Primary while (true) Toke t = get_toke(); // get the ext Toke switch (t.kid) case '*': left *= primary(); break; case '/': left /= primary(); break; default: retur left; // retur the value 23 Dealig with divide by 0 double term() // exactly like expressio(), but for * ad / double left = primary(); // get the Primary while (true) Toke t = get_toke(); // get the ext Toke switch (t.kid) case '*': left *= primary(); break; case '/': double d = primary(); if (d==0) error("divide by zero"); left /= d; break; default: retur left; // retur the value 24 Dealig with umbers ad paretheses double primary() // Number or ( Expressio ) Toke t = get_toke(); switch (t.kid) case '(': // hadle ( expressio ) double d = expressio(); t = get_toke(); if (t.kid!= ')') error("')' expected"); retur d; case '8': // we use 8 to represet the kid of a umber retur t.value; // retur the umber s value default: error("primary expected"); 25 6
Program orgaizatio The program Toke get_toke() error() #iclude "std_lib_facilities.h" // Toke stuff (explaied i the ext lecture) primary() double expressio(); // declaratio so that primary() ca call expressio() istream ci >> term() double primary() /* */ // deal with umbers ad paretheses double term() /* */ // deal with * ad / (pity about %) double expressio() /* */ // deal with + ad ostream cout << mai() expressio() it mai() /* */ // o ext slide Who calls whom? (ote the loop) 26 27 The program mai() A mystery it mai() try while (ci) cout << expressio() << '\'; keep_widow_ope(); // for some Widows versios catch (rutime_error& e) cerr << e.what() << edl; keep_widow_ope (); retur 1; catch ( ) cerr << "exceptio \"; keep_widow_ope (); retur 2; 28 2 3 4 2 a aswer 5+6 5 a aswer X Bad toke a aswer (fially, a expected aswer) 29 7
Expect mysteries A mystery Your first try rarely works as expected That s ormal ad to be expected Eve for experieced programmers If it looks as if it works be suspicious Ad test a bit more Now comes the debuggig Fidig out why the program misbehaves Ad do t expect your secod try to work either 1 2 3 4+5 6+7 8+9 10 11 12 1 a aswer 4 a aswer 6 a aswer 8 a aswer 10 a aswer A mystery Aha! Our program eats two out of three iputs How come? Let s have a look at expressio() 30 31 Dealig with + ad - Dealig with + ad - Expressio: Term Expressio + Term Expressio - Term // Note: every Expressio starts with a Term double expressio() // read ad evaluate: 1 1+2.5 1+2+3.14 etc. double left = term(); // get the Term while (true) Toke t = get_toke(); // get the ext toke switch (t.kid) // ad do the right thig with it case '+': left += term(); break; case '-': left -= term(); break; default: retur left; // <<< does t use ext toke 32 So, we eed a way to put back a toke! Put back ito what? the iput, of course: we eed a iput stream of tokes, a toke stream double expressio() // deal with + ad - double left = term(); while (true) Toke t = ts.get(); // get the ext toke from a toke stream switch (t.kid) case '+': left += term(); break; case '-': left -= term(); break; default: ts.putback(t); // put the uused toke back retur left; 33 8
Dealig with * ad / Now make the same chage to term() double term() // deal with * ad / double left = primary(); while (true) Toke t = ts.get(); // get the ext Toke from iput switch (t.kid) case '*': // deal with * case '/': // deal with / default: ts.putback(t); // put uused toke back ito iput stream retur left; 34 It sort of works The program That s ot bad for a first try Well, secod try Well, really, the fourth try; see the book But sort of works is ot good eough Whe the program sort of works is whe the work (ad fu) really start Now we ca get feedback! 35 Aother mystery The mai() program 2 3 4 2+3 2*3 2 a aswer 3 a aswer 4 a aswer 5 a aswer What! No 6? The program looks ahead oe toke It s waitig for the user So, we itroduce a prit result commad While we re at it, we also itroduce a quit commad it mai() double val = 0; while (ci) Toke t = ts.get(); // rather tha get_toke() if (t.kid == 'q') break; // q for quit if (t.kid == ';') // ; for prit ow cout << val << '\'; // prit result else ts. putback(t); // put a toke back ito the iput stream val = expressio(); // evaluate keep_widow_ope(); // exceptio hadlig 36 37 9
Now the calculator is miimally useful 2; 2 a aswer 2+3; 5 a aswer 3+4*5; 23 a aswer q Next lecture Completig a program Tokes Recoverig from errors Cleaig up the code Code review Testig 38 39 10