Chapter 6 Writing a Program Bjarne Stroustrup .
Post on 26-Mar-2015
258 Views
Preview:
Transcript
Chapter 6Chapter 6Writing a ProgramWriting a Program
Bjarne StroustrupBjarne Stroustrupwww.stroustrup.com/Programmingwww.stroustrup.com/Programming
OverviewOverview
Some thoughts on software developmentSome thoughts on software development The idea of a calculatorThe idea of a calculator Using a grammarUsing a grammar Expression evaluationExpression evaluation Program organizationProgram organization
33Stroustrup/ProgrammingStroustrup/Programming
Building a programBuilding a program
AnalysisAnalysis Refine our understanding of the problemRefine our understanding of the problem
Think of the final use of our programThink of the final use of our program
DesignDesign Create an overall structure for the programCreate an overall structure for the program
ImplementationImplementation Write codeWrite code DebugDebug TestTest
Go through these stages repeatedlyGo through these stages repeatedly
44Stroustrup/ProgrammingStroustrup/Programming
Writing a program: StrategyWriting a program: Strategy
What is the problem to be solved?What is the problem to be solved? Is the problem statement clear?Is the problem statement clear? Is the problem manageable, given the time, skills, and tools available?Is the problem manageable, given the time, skills, and tools available?
Try breaking it into manageable partsTry breaking it into manageable parts Do we know of any tools, libraries, etc. that might help?Do we know of any tools, libraries, etc. that might help?
Yes, even this early: Yes, even this early: iostreamiostreams, s, vectorvector, etc., etc. Build a small, limited version solving a key part of the problemBuild a small, limited version solving a key part of the problem
To bring out problems in our understanding, ideas, or toolsTo bring out problems in our understanding, ideas, or tools Possibly change the details of the problem statement to make it manageablePossibly change the details of the problem statement to make it manageable
If that doesn’t workIf that doesn’t work Throw away the first version and make another limited versionThrow away the first version and make another limited version Keep doing that until we find a version that we’re happy withKeep doing that until we find a version that we’re happy with
Build a full scale solutionBuild a full scale solution Ideally by using part of our initial versionIdeally by using part of our initial version
55Stroustrup/ProgrammingStroustrup/Programming
Writing a program: ExampleWriting a program: Example
I’ll build a program in stages, making lot of “typical I’ll build a program in stages, making lot of “typical mistakes” along the waymistakes” along the way Even experienced programmers make mistakesEven experienced programmers make mistakes
Lots of mistakes; it’s a necessary part of learningLots of mistakes; it’s a necessary part of learning
Designing a good program is genuinely difficultDesigning a good program is genuinely difficult It’s often faster to let the compiler detect gross mistakes than It’s often faster to let the compiler detect gross mistakes than
to try to get every detail right the first timeto try to get every detail right the first time Concentrate on the important design choicesConcentrate on the important design choices
Building a simple, incomplete version allows us to experiment Building a simple, incomplete version allows us to experiment and get feedbackand get feedback
Good programs are “grown”Good programs are “grown”
66Stroustrup/ProgrammingStroustrup/Programming
A simple calculatorA simple calculator
Given expressions as input from the keyboard, Given expressions as input from the keyboard, evaluate them and write out the resulting valueevaluate them and write out the resulting value For exampleFor example
Expression: 2+2Expression: 2+2 Result: 4Result: 4 Expression: 2+2*3Expression: 2+2*3 Result: 8Result: 8 Expression: 2+3-25/5Expression: 2+3-25/5 Result: 0Result: 0
Let’s refine this a bit more …Let’s refine this a bit more …
77Stroustrup/ProgrammingStroustrup/Programming
Pseudo CodePseudo Code
A first idea:A first idea:
int main()int main() {{
variablesvariables // // pseudo codepseudo codewhile (get a line) {while (get a line) { // // what’s a line?what’s a line?
analyze the expressionanalyze the expression // // what does that what does that mean?mean?
evaluate the expressionevaluate the expressionprint the resultprint the result
}}}}
HHow do we represent ow do we represent 45+5/745+5/7 as data? as data? HHow do we find ow do we find 45 + 5 / 45 + 5 / andand 7 7 in an input string? in an input string? How do we make sure that How do we make sure that 45+5/745+5/7 means means 45+(5/7)45+(5/7) rather than rather than (45+5)/7(45+5)/7?? Should we allow floating-point numbers (sure!)Should we allow floating-point numbers (sure!) CCan we have variables? an we have variables? v=7; m=9; v*mv=7; m=9; v*m (later) (later) 88Stroustrup/ProgrammingStroustrup/Programming
A simple calculatorA simple calculator
Wait!Wait! We are just about to reinvent the wheel!We are just about to reinvent the wheel! Read Chapter 6 for more examples of dead-end approachesRead Chapter 6 for more examples of dead-end approaches
What would the experts do?What would the experts do? Computers have been evaluating expressions for 50+ yearsComputers have been evaluating expressions for 50+ years There There hashas to be a solution! to be a solution! What What diddid the experts do? the experts do?
Reading is good for youReading is good for you Asking more experienced friends/colleagues can be far more Asking more experienced friends/colleagues can be far more
effective, pleasant, and time-effective than slogging along on your effective, pleasant, and time-effective than slogging along on your ownown
99Stroustrup/ProgrammingStroustrup/Programming
Expression GrammarExpression Grammar This is what the experts usually do – write a This is what the experts usually do – write a grammargrammar::
Expression :Expression :TermTermExpression ‘+’ Term Expression ‘+’ Term e.g.e.g., , 1+21+2,, (1-2)+3 (1-2)+3,, 2*3+1 2*3+1Expression ‘-’ TermExpression ‘-’ Term
Term :Term :PrimaryPrimaryTerm ‘*’ Primary Term ‘*’ Primary e.g.e.g., , 1*21*2, , (1-2)*3.5(1-2)*3.5Term ‘/’ PrimaryTerm ‘/’ PrimaryTerm ‘%’ PrimaryTerm ‘%’ Primary
Primary :Primary :NumberNumber e.g.e.g., , 11, , 3.53.5‘‘(‘ Expression ‘)’(‘ Expression ‘)’ e.g.e.g., , (1+2*3)(1+2*3)
Number :Number :floating-point literalfloating-point literal e.g.e.g., , 3.143.14, , 0.274e10.274e1, or , or 42 42 – as defined for – as defined for C++C++
A program is built out of Tokens (A program is built out of Tokens (e.g.e.g., numbers and operators)., numbers and operators). 1010Stroustrup/ProgrammingStroustrup/Programming
A side trip: GrammarsA side trip: Grammars
What’s a What’s a grammargrammar? ? A set of (syntax) rules for expressions.A set of (syntax) rules for expressions. The rules say how to analyze (“parse”) an expression.The rules say how to analyze (“parse”) an expression. Some seem hard-wired into our brainsSome seem hard-wired into our brains Example, you know what this means:Example, you know what this means:
2*3+4/22*3+4/2 birds fly but fish swimbirds fly but fish swim
You know that this is wrong:You know that this is wrong: 2 * + 3 4/22 * + 3 4/2 fly birds fish but swimfly birds fish but swim
Why is it right/wrong?Why is it right/wrong? How do we know?How do we know? How can we teach what we know to a computer?How can we teach what we know to a computer?
1111Stroustrup/ProgrammingStroustrup/Programming
Grammars – “English”Grammars – “English”
1212Stroustrup/ProgrammingStroustrup/Programming
Grammars - expressionGrammars - expression
1313Stroustrup/ProgrammingStroustrup/Programming
Grammars - expressionGrammars - expression
1414Stroustrup/ProgrammingStroustrup/Programming
Grammars - expressionGrammars - expression
1515Stroustrup/ProgrammingStroustrup/Programming
Functions for parsingFunctions for parsing
WWe need functions to match the grammar rulese need functions to match the grammar rules
get()get() //// read characters and compose tokensread characters and compose tokens//// calls calls cincin for input for input
expression()expression() //// deal with + and –deal with + and –//// calls calls term() term() andand get() get()
term ()term () //// deal with *, /, and %deal with *, /, and %//// calls calls primary() primary() andand get() get()
primary()primary() //// deal with numbers and parenthesesdeal with numbers and parentheses//// calls calls expression() expression() andand get() get()
NoteNote: each function deals with a specific part of an expression and leaves: each function deals with a specific part of an expression and leaveseverything else to other functions – this radically simplifies each function.everything else to other functions – this radically simplifies each function.
AnalogyAnalogy: a group of people can deal with a complex problem by each person: a group of people can deal with a complex problem by each personhandling only problems in his/her own specialty, leaving the rest for colleagues.handling only problems in his/her own specialty, leaving the rest for colleagues.
1616Stroustrup/ProgrammingStroustrup/Programming
Function Return TypesFunction Return Types
What should the parser functions return? What should the parser functions return? How about the result?How about the result?
Token get();Token get(); //// read characters and compose tokensread characters and compose tokensdouble expression();double expression(); //// deal with + and –deal with + and –
//// return the sum (or difference)return the sum (or difference)double term ();double term (); //// deal with *, /, and %deal with *, /, and %
//// return the product (or …)return the product (or …)double primary();double primary(); //// deal with numbers and parenthesesdeal with numbers and parentheses
//// return the valuereturn the value
What is a What is a TokenToken??
1717Stroustrup/ProgrammingStroustrup/Programming
What is a token?What is a token?
We want to see input as a stream of tokensWe want to see input as a stream of tokens We read charactersWe read characters 1 + 4*(4.5-6) 1 + 4*(4.5-6) (That’s 13 characters incl. 2 spaces)(That’s 13 characters incl. 2 spaces) 9 tokens in that expression: 9 tokens in that expression: 1 + 4 * ( 4.5 - 6 )1 + 4 * ( 4.5 - 6 ) 6 kinds of tokens in that expression: number 6 kinds of tokens in that expression: number + * ( - )+ * ( - )
We want each token to have two partsWe want each token to have two parts A “kind”; e.g., numberA “kind”; e.g., number A value; e.g., A value; e.g., 44
We need a type to represent this “Token” ideaWe need a type to represent this “Token” idea We’ll build that in the next lecture, but for now:We’ll build that in the next lecture, but for now:
get_token()get_token() gives us the next token from input gives us the next token from input t.kindt.kind gives us the kind of the token gives us the kind of the token t.valuet.value gives us the value of the token gives us the value of the token
1818
+number
4.5
Stroustrup/ProgrammingStroustrup/Programming
Dealing with + and -Dealing with + and -
Expression:Expression:TermTermExpression ‘+’ TermExpression ‘+’ Term // // Note: every Expression starts with a TermNote: every Expression starts with a TermExpression ‘-’ TermExpression ‘-’ Term
double expression()double expression() // // read and evaluate: 1 1+2.5 1+2+3.14 etc.read and evaluate: 1 1+2.5 1+2+3.14 etc.{{
double left = term(); double left = term(); // // get the Termget the Termwhile (true) {while (true) {
Token t = get_token();Token t = get_token(); // // get the next token…get the next token…switch (t.kind) {switch (t.kind) { // // … and do the right thing with it… and do the right thing with itcase '+':case '+': left += term(); break; left += term(); break;case '-':case '-': left -= term(); break; left -= term(); break;default:default: return left;return left; // // return the value of the return the value of the
expressionexpression}}
}}}}
1919Stroustrup/ProgrammingStroustrup/Programming
Dealing with *, /, and %Dealing with *, /, and %
double term()double term() // // exactly like expression(), but for *, /, and %exactly like expression(), but for *, /, and %{{
double left = primary(); double left = primary(); // // get the Primaryget the Primarywhile (true) {while (true) {
Token t = get_token();Token t = get_token(); // // get the next Token…get the next Token…switch (t.kind) {switch (t.kind) {case '*':case '*': left *= primary(); break; left *= primary(); break;case '/':case '/': left /= primary(); break; left /= primary(); break;case '%': left %= primary(); break;case '%': left %= primary(); break;default:default: return left;return left; // // return the valuereturn the value}}
}}}}
Oops: doesn’t compileOops: doesn’t compile % isn’t defined for floating-point numbers% isn’t defined for floating-point numbers
2020Stroustrup/ProgrammingStroustrup/Programming
Dealing with * and /Dealing with * and /Term :Term :
PrimaryPrimaryTerm ‘*’ Primary Term ‘*’ Primary // // Note: every Term starts with a PrimaryNote: every Term starts with a PrimaryTerm ‘/’ PrimaryTerm ‘/’ Primary
double term()double term() // // exactly like expression(), but for *, and /exactly like expression(), but for *, and /{{
double left = primary(); double left = primary(); // // get the Primaryget the Primarywhile (true) {while (true) {
Token t = get_token();Token t = get_token(); // // get the next Tokenget the next Tokenswitch (t.kind) {switch (t.kind) {case '*':case '*': left *= primary(); break; left *= primary(); break;case '/':case '/': left /= primary(); break; left /= primary(); break;default:default: return left;return left; // // return the valuereturn the value}}
}}}}
2121Stroustrup/ProgrammingStroustrup/Programming
Dealing with divide by 0Dealing with divide by 0double term()double term() // // exactly like expression(), but for * and /exactly like expression(), but for * and /{{
double left = primary(); double left = primary(); // // get the Primaryget the Primarywhile (true) {while (true) {Token t = get_token();Token t = get_token(); // // get the next Tokenget the next Tokenswitch (t.kind) {switch (t.kind) {case '*':case '*':left *= primary();left *= primary();break;break;case '/':case '/':{{ double d = primary();double d = primary();if (d==0) error("divide by zero");if (d==0) error("divide by zero");left /= d;left /= d;break;break;}}default:default:return left;return left; // // return the valuereturn the value}}}}
}}
2222Stroustrup/ProgrammingStroustrup/Programming
Dealing with numbers and parenthesesDealing with numbers and parentheses double primary()double primary() // // Number or ‘(‘ Expression ‘)’Number or ‘(‘ Expression ‘)’{{
Token t = get_token();Token t = get_token();switch (t.kind) {switch (t.kind) {case '(':case '(': // // handle ‘(’expression ‘)’handle ‘(’expression ‘)’{{ double d = expression();double d = expression();
t = get_token();t = get_token();if (t.kind != ')') error("')' expected");if (t.kind != ')') error("')' expected");return d;return d;
}}case '8':case '8': // // we use ‘8’ to represent the “kind” of a numberwe use ‘8’ to represent the “kind” of a number
return t.value;return t.value; // // return the number’s valuereturn the number’s valuedefault:default:
error("primary expected");error("primary expected");}}
}}2323Stroustrup/ProgrammingStroustrup/Programming
Program organizationProgram organization
Who calls who? Who calls who? (note the loop)(note the loop)2424
primary()
expression()
term()
main()
istreamcin>>
error()Token
ostreamcout<<
get_token()
Stroustrup/ProgrammingStroustrup/Programming
The programThe program
#include "std_lib_facilities.h"#include "std_lib_facilities.h"
// // Token stuff (explained in the next lecture)Token stuff (explained in the next lecture)
double expression(); // double expression(); // declaration so that primary() can call declaration so that primary() can call expression()expression()
double primary() { /* double primary() { /* …… */ } */ } // // deal with numbers and parenthesesdeal with numbers and parenthesesdouble term() { /* double term() { /* …… */ } */ } //// deal with * and / (pity about %)deal with * and / (pity about %)double expression() { /* double expression() { /* …… */ } */ } //// deal with + and –deal with + and –
int main() { /* int main() { /* …… */ } */ } // // on next slideon next slide
2525Stroustrup/ProgrammingStroustrup/Programming
The program – main()The program – main()
int main()int main()try {try {
while (cin)while (cin) cout << expression() << '\n';cout << expression() << '\n';
keep_window_open();keep_window_open(); // // for some Windows versionsfor some Windows versions}}catch (runtime_error& e) {catch (runtime_error& e) {
cerr << e.what() << endl;cerr << e.what() << endl;keep_window_open ();keep_window_open ();return 1;return 1;
}}catch (…) {catch (…) {
cerr << "exception \n";cerr << "exception \n";keep_window_open ();keep_window_open ();return 2;return 2;
}}2626Stroustrup/ProgrammingStroustrup/Programming
A mysteryA mystery
22 33 44 22 an answeran answer 5+65+6 55 an answeran answer XX Bad tokenBad token an answer (finally, an expected answer)an answer (finally, an expected answer)
2727Stroustrup/ProgrammingStroustrup/Programming
A mysteryA mystery
1 2 3 4+5 6+7 8+9 10 11 121 2 3 4+5 6+7 8+9 10 11 12 11 an answeran answer 44 an answeran answer 66 an answeran answer 88 an answeran answer 1010 an answeran answer
Aha! Our program “eats” two out of three inputsAha! Our program “eats” two out of three inputs How come?How come? Let’s have a look at expression()Let’s have a look at expression()
2828Stroustrup/ProgrammingStroustrup/Programming
Dealing with + and -Dealing with + and -
Expression:Expression:TermTermExpression ‘+’ TermExpression ‘+’ Term // // Note: every Expression starts with a TermNote: every Expression starts with a TermExpression ‘-’ TermExpression ‘-’ Term
double expression()double expression() // // read and evaluate: 1 1+2.5 1+2+3.14 etc.read and evaluate: 1 1+2.5 1+2+3.14 etc.{{
double left = term(); double left = term(); // // get the Termget the Termwhile (true) {while (true) {
Token t = get_token();Token t = get_token(); // // get the next token…get the next token…switch (t.kind) {switch (t.kind) { // // … and do the right thing with it… and do the right thing with itcase '+':case '+': left += term(); break; left += term(); break;case '-':case '-': left -= term(); break; left -= term(); break;default:default: return left;return left; // // <<< doesn’t use “next token”<<< doesn’t use “next token”}}
}}}} 2929Stroustrup/ProgrammingStroustrup/Programming
Dealing with + and -Dealing with + and -
So, we need a way to “put back” a token!So, we need a way to “put back” a token! Back into what?Back into what? ““the input,” of course; that is, we need an input stream of tokensthe input,” of course; that is, we need an input stream of tokens
double expression()double expression() // // deal with + and -deal with + and -{{
double left = term(); double left = term(); while (true) {while (true) {
Token t = ts.get();Token t = ts.get(); // // get the next token from a “token get the next token from a “token stream”stream”
switch (t.kind) {switch (t.kind) {case '+':case '+': left += term(); break; left += term(); break;case '-':case '-': left -= term(); break; left -= term(); break;default:default: ts.putback(t); // ts.putback(t); // put the unused token backput the unused token back
return left;return left;}}
}}}}
3030Stroustrup/ProgrammingStroustrup/Programming
Dealing with * and /Dealing with * and / Now make the same change to Now make the same change to term()term()
double term()double term() // // deal with * and /deal with * and /{{
double left = primary(); double left = primary(); while (true) {while (true) {
Token t = ts.get();Token t = ts.get(); // // get the next Token from inputget the next Token from inputswitch (t.kind) {switch (t.kind) {case '*':case '*':
// // deal with *deal with *case '/':case '/':
// // deal with /deal with /default:default:
ts.putback(t);ts.putback(t); // // put unused token back into input streamput unused token back into input streamreturn left;return left;
}}}}
}}
3131Stroustrup/ProgrammingStroustrup/Programming
The programThe program
It “sort of works”It “sort of works” That’s not bad for a first tryThat’s not bad for a first try
Well, second tryWell, second try Well, really, the fourth try; see the bookWell, really, the fourth try; see the book
But “sort of works” is not good enoughBut “sort of works” is not good enough When the program “sort of works” is when the work (and When the program “sort of works” is when the work (and
fun) really startfun) really start Now we can get feedback!Now we can get feedback!
3232Stroustrup/ProgrammingStroustrup/Programming
Another mysteryAnother mystery
2 3 4 2+3 2*32 3 4 2+3 2*3 22 an answeran answer 33 an answeran answer 44 an answeran answer 55 an answeran answer
What! No “6” ?What! No “6” ? The program looks ahead one tokenThe program looks ahead one token
It’s waiting for the userIt’s waiting for the user
So, we introduce a “print result” commandSo, we introduce a “print result” command While we’re at it, we also introduce a “quit” commandWhile we’re at it, we also introduce a “quit” command
3333Stroustrup/ProgrammingStroustrup/Programming
The main() programThe main() program
int main()int main(){{
double val = 0;double val = 0;while (cin) {while (cin) {
Token t = ts.get();Token t = ts.get(); // // rather than get_token()rather than get_token()if (t.kind == 'q') break;if (t.kind == 'q') break; // // ‘q’ for “quit”‘q’ for “quit”if (t.kind == ';')if (t.kind == ';') // // ‘;’ for “print now”‘;’ for “print now”
cout << val << '\n';cout << val << '\n'; // // print resultprint resultelseelse
ts. ts. putbackputback(t);(t); // // put a token back into the input put a token back into the input streamstream
val = expression();val = expression(); // // evaluateevaluate}}keep_window_open();keep_window_open();
}}// // … exception handling …… exception handling … 3434Stroustrup/ProgrammingStroustrup/Programming
Now the calculator is minimally usefulNow the calculator is minimally useful 2;2; 22 an answeran answer 2+3;2+3; 55 an answeran answer 3+4*5;3+4*5; 2323 an answeran answer qq
3535Stroustrup/ProgrammingStroustrup/Programming
Next lectureNext lecture
Completing a programCompleting a program TokensTokens Recovering from errorsRecovering from errors Cleaning up the codeCleaning up the code Code reviewCode review TestingTesting
3636Stroustrup/ProgrammingStroustrup/Programming
top related