Top Banner
Chapter 6 Chapter 6 Writing a Program Writing a Program Bjarne Stroustrup Bjarne Stroustrup www.stroustrup.com/Programming www.stroustrup.com/Programming
35
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Chapter 6 Writing a Program Bjarne Stroustrup .

Chapter 6Chapter 6Writing a ProgramWriting a Program

Bjarne StroustrupBjarne Stroustrupwww.stroustrup.com/Programmingwww.stroustrup.com/Programming

Page 2: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 3: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 4: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 5: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 6: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 7: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 8: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 9: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 10: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 11: Chapter 6 Writing a Program Bjarne Stroustrup .

Grammars – “English”Grammars – “English”

1212Stroustrup/ProgrammingStroustrup/Programming

Page 12: Chapter 6 Writing a Program Bjarne Stroustrup .

Grammars - expressionGrammars - expression

1313Stroustrup/ProgrammingStroustrup/Programming

Page 13: Chapter 6 Writing a Program Bjarne Stroustrup .

Grammars - expressionGrammars - expression

1414Stroustrup/ProgrammingStroustrup/Programming

Page 14: Chapter 6 Writing a Program Bjarne Stroustrup .

Grammars - expressionGrammars - expression

1515Stroustrup/ProgrammingStroustrup/Programming

Page 15: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 16: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 17: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 18: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 19: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 20: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 21: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 22: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 23: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 24: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 25: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 26: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 27: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 28: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 29: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 30: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 31: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 32: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 33: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 34: Chapter 6 Writing a Program Bjarne Stroustrup .

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

Page 35: Chapter 6 Writing a Program Bjarne Stroustrup .

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