Download presentation

Presentation is loading. Please wait.

Published byWarren Cole Modified over 2 years ago

1
SEG 2106 Software Construction Instructor: Hussein Al Osman the course Material is Based on the course constructed by Profs: Gregor v. Bochmann (https://www.site.uottawa.ca/~bochmann/) Jiying Zhao (http://www.site.uottawa.ca/~jyzhao/)

2
**Course Sections Section 0: Introduction**

Section 1: Software development processes + Domain Analysis Section 2: Requirements + Behavioral Modeling (Activity Diagrams) Section 3: More Behavioral Modeling (State Machines) Section 4: More Behavioral Modeling (Case Study) Section 5: Petri Nets Section 6: Introduction to Compilers Section 7: Lexical Analysis Section 8: Finite State Automata Section 9: Practical Regular Expressions Section 10: Introduction to Syntax Analysis Section 11: LL(1) Parser Section 12: More on LL Parsing (Error Recovery and non LL(1) Parsers) Section 13: LR Parsing Section 14: Introduction to Concurrency Section 15: More on Concurrency Section 16: Java Concurrency Section 17: Process Scheduling Section 18: Web Services

3
Section 0 Syllabus

4
Welcome to SEG2106

5
Course Information Instructor: Hussein Al Osman Office: SITE4043 Office Hours: TBD Web Site: Virtual Campus (https://maestro.uottawa.ca) Lectures: Wednesday 13: :30 STE C0136 Friday MRT 211 Labs: Monday 17: :30 STE 2052 Tuesday 19: :00 STE 0131

6
Evaluation Scheme Assignments (4) 25% Labs (7) 15% Midterm Exam 20% Final Exam 40% Late assignments are accepted for a maximum of 24 hours and they will receive a 30% penalty.

7
**Labs Seven labs in total Three formal labs (with a report)**

Worth between 3 to 4% The other labs are informal (without a report) 1% for each one You show you work to the TA at the end of the session

8
Informal Labs Your mark will be proportional to the number of task successfully completed: All the tasks are completed: 1% More than half completed: 0.75% Almost half is completed: 0.5% You have tried at least (given that you attended the whole session): 0.25%

9
**Major Course Topics Chapter 1: Introduction and Behavioral Modeling**

Introduction to software development processes Waterfall model Iterative (or incremental) model Agile model Behavioral modeling UML Use case models (seen previously) UML Sequence diagrams (seen previously) UML activity diagrams (very useful to model concurrent behavior) UML state machines (model the behavior of a single object) Petri Nets SDL

10
Major Course Topics Chapter 2: Compilers, formal languages and grammars Lexical analysis (convert a sequence of characters into a sequence of tokens) Formal languages Regular expressions (method to describe strings) Deterministic and Non-deterministic Finite Automata Syntax analysis Context-free grammar (describes the syntax of a programming language) Syntactic analysis Syntax trees

11
**Major Course Topics Chapter 3: Concurrency**

Logical and physical concurrency Process scheduling Mutual exclusion for access to shared resources Concurrency and Java programing Design patterns and performance considerations

12
Major Course Topics Chapter 4: Cool topics! We will vote on one or more of these topics to cover (given that we have completed the above described material, with some time to spare) Mobile programing (mostly Android) Web services J2EE major components Spring framework Agile programing (especially SCRUM) Other suggestions…

13
**Class Policies Late Assignments**

Late assignments are accepted for a maximum of 24 hours and they will receive a 30% penalty.

14
**Class Policies Plagiarism**

Plagiarism is a serious academic offence that will not be tolerated. Note that the person providing solutions to be copied is also committing an offence as they are an active participant in the plagiarism. The person copying and the person copied from will be reprimanded equally according to the regulations set by the University of Ottawa. Please refer to this link for more information:

15
**Class Policies Attendance**

Class attendance is mandatory. As per academic regulations, students who do not attend 80% of the class will not be allowed to write the final examinations. All components of the course (i.e laboratory reports, assignments, etc.) must be fulfilled otherwise students may receive an INC as a final mark (equivalent to an F). Absence from a laboratory session or an examination because of illness will be excused only if you provide a certificate from Health Services (100 Marie Curie, 3rd Floor) within the week following your absence.

16
**Software development process and Domain Analysis**

Section 1 Software development process and Domain Analysis

17
Lecture Topics This lecture will briefly touch on the following topics: Software Development Process Domain Analysis

18
**Software Development Process**

Topic 1 Software Development Process

19
**Life cycle The life cycle of a software product**

from inception of an idea for a product through domain analysis requirements gathering architecture design and specification coding and testing delivery and deployment maintenance and evolution retirement

20
**Models are needed Symptoms of inadequacy: the software crisis**

scheduled time and cost exceeded user expectations not met poor quality The size and economic value of software applications required appropriate "process models"

21
Process as a "black box"

22
Problems The assumption is that requirements can be fully understood prior to development Unfortunately the assumption almost never holds Interaction with the customer occurs only at the beginning (requirements) and end (after delivery)

23
Process as a "white box"

24
**Advantages Reduce risks by improving visibility**

Allow project changes as the project progresses based on feedback from the customer

25
**The main activities They must be performed independently of the model**

The model simply affects the flow among activities

26
Waterfall models Invented in the late 1950s for large air defense systems, popularized in the 1970s They organize activities in a sequential flow Standardize the outputs of the various activities (deliverables) Exist in many variants, all sharing sequential flow style

27
**A Waterfall models Domain analysis and feasibility study Requirements**

Design Coding and module testing Integration and system testing Delivery, deployment, and maintenance

28
Waterfall Strengths Easy to understand, easy to use Provides structure to inexperienced staff Milestones are well understood Sets requirements stability

29
Waterfall Weaknesses All requirements must be known upfront Deliverables created for each phase are considered frozen – inhibits flexibility Can give a false impression of progress Does not reflect problem-solving nature of software development – iterations of phases Integration is one big bang at the end Little opportunity for customer to preview the system (until it may be too late)

30
**When to use waterfall Requirements are very well known**

Product definition is stable Technology is very well understood New version of an existing product (maybe!) Porting an existing product to a new platform High risk for new systems because of specification and design problems. Low risk for well-understood developments using familiar technology.

31
**Waterfall – With Feedback**

Domain analysis and feasibility study Requirements Design Coding and module testing Integration and system testing Delivery, deployment, and maintenance

32
**Iterative Development Process**

Also referred to as incremental development process Develop system through repeated cycle (iterations) Each cycle is responsible for the development of a small portion of the solution (slice of functionality) Contrast with waterfall: Water fall is a special iterative process with only one cycle

33
**Iterative Development Process**

Domain Analysis and Initial Planning Requirements Update Architecture and Design Cycle Iteration Planning Implementation Evaluation (involving end user) Testing Deployment

34
Agile Methods Dissatisfaction with the overheads involved in software design methods of the 1980s and 1990s led to the creation of agile methods. These methods: Focus on the code rather than the design Are based on an iterative approach to software development Are intended to deliver working software quickly and evolve this quickly to meet changing requirements The aim of agile methods is to reduce overheads in the software process (e.g. by limiting documentation) and to be able to respond quickly to changing requirements without excessive rework.

35
Agile Manifesto We are uncovering better ways of developing software by doing it and helping others do it. Through this work we have come to value: Individuals and interactions over processes and tools Working software over comprehensive documentation Customer collaboration over contract negotiation Responding to change over following a plan That is, while there is value in the items on the right, we value the items on the left more.

36
**The principles of agile methods**

Description Customer involvement Customers should be closely involved throughout the development process. Their role is to provide and prioritize new system requirements and to evaluate the iterations of the system. Incremental delivery The software is developed in increments with the customer specifying the requirements to be included in each increment. People not process The skills of the development team should be recognized and exploited. Team members should be left to develop their own ways of working without prescriptive processes. Embrace change Expect the system requirements to change and so design the system to accommodate these changes. Maintain simplicity Focus on simplicity in both the software being developed and in the development process. Wherever possible, actively work to eliminate complexity from the system.

37
SCRUM Process

38
**Problems with agile methods**

It can be difficult to keep the interest of customers who are involved in the process Team members may be unsuited to the intense involvement that characterizes agile methods Prioritizing changes can be difficult where there are multiple stakeholders Minimizing documentation: almost nothing is captured, the code is the only authority

39
Topic 2 Domain Analysis

40
Domain Modeling The aim of domain analysis is to understand the problem domain independently of the particular system we intend to develop. We do not try to draw the borderline between the system and the environment. We focus on the concepts and the terminology of the application domain with a wider scope than the future system.

41
**Activities and Results of Domain Analysis**

A dictionary of terms defining the common terminology and concepts of the problem domain; Description of the problem domain from a conceptual modeling viewpoint We normally use UML class diagrams (with as little detail as possible) Remember, we are not designing, but just establishing the relationship between entities Briefly describe the main interactions between the user and the system

42
**Example – Problem Definition**

43
**Example – Problem Definition**

We want to design the software for a simple Point of Sale Terminal that operates as follows: Displays that amount of money to pay for the goods to be purchased Asks the user to insert a financial card (debit or credit) If the user inserts a debit card, he or she is asked to choose the account type Asks the user to enter a pin number Verifies the pin number against the one stored on the chip Contacts the bank associated with the card in order to perform the transaction

44
**Example – Dictionary of Terms (1)**

Point of Sale Terminal: machine that allows a retail transaction to be completed using a financial card Credit card: payment card issued to users as a system of payment. It allows the cardholder to pay for goods and services based on the holder's promise to pay for them Debit card: plastic payment card that provides the cardholder electronic access to his or her bank account

45
**Example – Dictionary of Terms (2)**

Bank: financial institution that issues financial cards and where the user has at least one account into which he or she can withdraw or deposit money Bank Account: is a financial account between a user and a financial institution… User: client of that possesses a debit card and benefits from the use of a point of sale terminal Pin number: personal identification number (PIN, pronounced "pin"; often erroneously PIN number) is a secret numeric password shared between a user and a system that can be used to authenticate the user to the system

46
**Example – Problem Domain**

PinNumber 1 User FinancialCard * * 1..2 BankAccount * DebitCard CreditCard 1 PosTerminal 1..* Bank

47
**Example – Main Interactions**

Inputs to POS Terminal: Insertion of Financial Card, Pin Number, Specify Account, Confirm purchase… Outputs from POS Terminal: Error Message (regarding pin or funds), Confirmation of Purchase,

48
**Requirements Behavioral Modeling**

Section 2 Requirements Behavioral Modeling

49
**Topics Review of some notions regarding requirements**

Client requirements Functional requirements Non-functional requirements Introduction to Behavioral Modeling Activity Diagrams

50
Topic 1 Requirements

51
**Requirements We will describe three types of requirements:**

Customer requirements (a.k.a informal or business requirements) Functional requirements Non-functional requirements

52
**Customer Requirements**

We have completed the domain analysis, we are ready to get our hands dirty We need to figure out exactly what the customer wants: Customer Requirements This is where the expectations of the customer are captured Composed typically of high level, non-technical statements Example Requirement 1: “We need to develop an online customer portal” Requirement 2: “The portal must list all our products” …

53
**Functional Requirements**

Capture the intended behavior of the system May be expressed as services, tasks or functions the system performs Use cases have quickly become a widespread practice for capturing functional requirements This is especially true in the object-oriented community where they originated Their applicability is not limited to object-oriented systems

54
Use Cases A use case defines a goal-oriented set of interactions between external actors and the system under consideration Actors are parties outside the system that interact with the system An actor may be a class of users or other systems A use case is initiated by a user with a particular goal in mind, and completes successfully when that goal is satisfied It describes the sequence of interactions between actors and the system necessary to deliver the service that satisfies the goal

55
Use Case Diagrams

56
Use Case Diagrams Include relationship: use case fragment that is duplicated in multiple use cases Extend relationship: use case conditionally adds steps to another first class use case Example:

57
**Use Case – ATM Example Actors: ATM Customer ATM Operator Use Cases:**

The customer can withdraw funds from a checking or savings account query the balance of the account transfer funds from one account to another The ATM operator can Shut down the ATM Replenish the ATM cash dispenser Start the ATM

58
Use Case – ATM Example It can be seen that the first part of each use case - namely, reading the ATM card and validating the customer's PIN - is common to all three use cases. This common part of the three use cases is factored out as an inclusion use case called Validate PIN.

59
**Use Case – ATM Example Validate PIN is an Inclusion Use Case**

It cannot be executed on its own Must be executed as part of a Concrete Use Case On the other hand, a Concrete Use Case can be executed Inclusion use cases always reflect functionality that is common to more than one use case. When this common functionality is separated into an inclusion use case, the inclusion use case can be reused by several base (executable) use cases. Inclusion use cases can often be developed only after an initial iteration in which several use cases have been developed. Only then can repeated sequences of interactions be observed that form the basis for the inclusion use cases.

60
**Use Case – Validate PIN (1)**

Use case name: Validate PIN Summary: System validates customer PIN Actor: ATM Customer Precondition: ATM is idle, displaying a Welcome message.

61
**Use Case – Validate PIN (2)**

Main sequence: Customer inserts the ATM card into the card reader. If system recognizes the card, it reads the card number. System prompts customer for PIN. Customer enters PIN. System checks the card's expiration date and whether the card has been reported as lost or stolen. If card is valid, system then checks whether the user-entered PIN matches the card PIN maintained by the system. If PIN numbers match, system checks what accounts are accessible with the ATM card. System displays customer accounts and prompts customer for transaction type: withdrawal, query, or transfer.

62
**Use Case – Validate PIN (3)**

Alternative sequences: Step 2: If the system does not recognize the card, the system ejects the card. Step 5: If the system determines that the card date has expired, the system confiscates the card. Step 5: If the system determines that the card has been reported lost or stolen, the system confiscates the card. Step 7: If the customer-entered PIN does not match the PIN number for this card, the system re-prompts for the PIN. Step 7: If the customer enters the incorrect PIN three times, the system confiscates the card. Steps 4-8: If the customer enters Cancel, the system cancels the transaction and ejects the card. Postcondition: Customer PIN has been validated.

63
**Use Case – Withdraw Funds (1)**

Use case name: Withdraw Funds Summary: Customer withdraws a specific amount of funds from a valid bank account. Actor: ATM Customer Dependency: Include Validate PIN use case. Precondition: ATM is idle, displaying a Welcome message.

64
**Use Case – Withdraw Funds (2)**

Main sequence: Include Validate PIN use case. Customer selects Withdrawal, enters the amount, and selects the account number. System checks whether customer has enough funds in the account and whether the daily limit will not be exceeded. If all checks are successful, system authorizes dispensing of cash. System dispenses the cash amount. System prints a receipt showing transaction number, transaction type, amount withdrawn, and account balance. System ejects card. System displays Welcome message.

65
**Use Case – Withdraw Funds (3)**

Alternative sequences: Step 3: If the system determines that the account number is invalid, then it displays an error message and ejects the card. Step 3: If the system determines that there are insufficient funds in the customer's account, then it displays an apology and ejects the card. Step 3: If the system determines that the maximum allowable daily withdrawal amount has been exceeded, it displays an apology and ejects the card. Step 5: If the ATM is out of funds, the system displays an apology, ejects the card, and shuts down the ATM. Postcondition: Customer funds have been withdrawn.

66
**Non-Functional Requirements**

Functional requirements define what a system is supposed to do Non-functional requirements define how a system is supposed to be Usually describe system attributes such as security, reliability, maintainability, scalability, usability…

67
**Non-Functional Requirements**

Non-Functional requirements can be specified in a separate section of the use case description In the previous example, for the Validate PIN use case, there could be a security requirement that the card number and PIN must be encrypted Non-Functional requirements can be specified for a group of use cases or the whole system Security requirement: System shall encrypt ATM card number and PIN. Performance requirement: System shall respond to actor inputs within 5 seconds.

68
Topic 2 Behavioral Modeling

69
Software Modeling UML defines thirteen basic diagram types, divided into two general sets: Structural Modeling Behavioral Modeling Structural Models define the static architecture of a model They are used to model the “things” that make up a model – the classes, objects, interfaces and physical components In addition they are used to model the relationships and dependencies between elements

70
Behavioral Modeling Behavior Models capture the dynamic behavior of a system as it executes over time They provide a view of a system in which control and sequencing are considered Either within an object (by means of a finite state machine) or between objects (by analysis of object interactions).

71
UML Activity Diagrams In UML an activity diagram is used to display the sequence of actions They show the workflow from start to finish Detail the many decision paths that exist in the progression of events contained in the activity Very useful when parallel processing may occur in the execution of some activities

72
UML Activity Diagrams An example of an activity diagram is shown below (We will come back to that diagram)

73
Activity An activity is the specification of a parameterized sequence of behavior Shown as a round-cornered rectangle enclosing all the actions and control flows

74
**Actions and Constrains**

An action represents a single step within an activity Constraints can be attached to actions

75
**Control Flow Shows the flow of control from one action to the next**

Its notation is a line with an arrowhead. Initial Node Final Node, two types: Activity Final Node Flow Final Node

76
Objects Flow An object flow is a path along which objects or data can pass An object is shown as a rectangle A short hand for the above notation

77
**Decision and Merge Nodes**

Decision nodes and merge nodes have the same notation: a diamond shape The control flows coming away from a decision node will have guard conditions

78
Fork and Join Nodes Forks and joins have the same notation: either a horizontal or vertical bar They indicate the start and end of concurrent threads of control Join synchronizes two inflows and produces a single outflow The outflow from a join cannot execute until all inflows have been received

79
**Partition Shown as horizontal or vertical swim lane**

Represents a group of actions that have some common characteristic

80
UML Activity Diagrams Coming back to our initial example

81
**Issue Handling in Software Projects**

Courtesy of uml-diagrams.org

82
**More on Activity Diagrams**

Interruptible Activity Regions Expansion Regions Exception Handlers

83
**Interruptible Activity Region**

Surrounds a group of actions that can be interrupted Example below: “Process Order” action will execute until completion, when it will pass control to the “Close Order” action, unless a “Cancel Request” interrupt is received, which will pass control to the “Cancel Order” action.

84
Expansion Region An expansion region is an activity region that executes multiple times to consume all elements of an input collection Example of books checkout at a library modeled using an expansion region: Checkout Books Find Books to Borrow Checkout Book Show Due Date Place Books in Bags

85
**Extract Audio from Frame**

Expansion Region Another example: Encoding Video Encode Video Capture Video Extract Audio from Frame Encode Video Frame Save Encoded Video Attach Audio to Frame

86
Exception Handlers An exception handler is an element that specifies what to execute in case the specified exception occurs during the execution of the protected node In Java “Try block” corresponds to “Protected Node” “Catch block” corresponds to the “Handler Body Node”

87
Section 3 Behavioral Modeling

88
Topics We will continue with the subject of Behavioral Modeling Introduce the various components of UML state machines

89
**Activity Diagrams vs State Machines**

In Activity Diagrams Vertices represent Actions Edges (arrows) represent transition that occurs at the completion of one action and before the start of another one (control flow) Vertex representing an Action Arrow implying transition from one action to another

90
**Activity Diagrams vs State Machines**

In State Machines Vertices represent states of a process Edges (arrows) represent occurrences of events Vertex representing a State Arrow representing an event

91
**UML State Machines Used to model the dynamic behaviour of a process**

Can be used to model a high level behaviour of an entire system Can be used to model the detailed behaviour of a single object All other possible levels of detail in between these extremes is also possible

92
**UML State Machine Example**

Example of a garage door state machine (We will come back to this example later)

93
**States Symbol for a state**

A system in a state will remain in it until the occurrence of an event that will cause it to transition to another one Being in a state means that a system will behave in a predetermined way in response to a given event Symbols for the initial and final states

94
States Numerous types of events can cause the system to transition from one state to another In every state, the system behaves in a different matter Names for states are usually chosen as: Adjectives: open, closed, ready… Present continuous verbs: opening, closing, waiting…

95
Transitions Transitions are represented with arrows

96
Transitions Transitions represent a change in a state in response to an event Theoretically, it is supposed to occur in a instantaneous manner (it does not take time to execute) A transition can have” Trigger: causes the transition; can be an event of simply the passage of time Guard: a condition that must evaluate to true for the transition to occur Effect: an action that will be invoked directly on the system of the object being modeled (if we are modeling an object, the effect would correspond to a specific method)

97
**State Actions An effect can also be associated with a state**

If a destination state is associated with numerous incident transitions (transitions arriving a that state), and every transition defines the same effect: The effect can therefore be associated with the state instead of the transitions (avoid duplications) This can be achieved using an “On Entry” effect (we can have multiple entry effects) We can also add one or more “On Exit” effect

98
**Self Transition State can also have self transitions**

These self transition are more useful when they have an effect associated with them Timer events are usually popular with self transitions Below is a typical example:

99
**Coming back to Our Initial Example**

Example of a garage door state machine

100
Decisions Just like activity diagrams, we can use decisions nodes (although we usually call them decision pseudo-states) Decision pseudo-states are represented with a diamond We always have one input transition and multiple outputs The branch of execution is decided by the guards associated with the transitions coming out of the decision pseudo-state

101
Decisions

102
Compound States A state machine can include several sub-machines Below is an example of a sub-machine included in the compound state “Connected” Connected Waiting disconnect Disconnected receiveByte byteProcessed connect ProcessingByte closeSession

103
**Compound States Example**

104
**Compound States Example**

Same example, with an alternative notation The link symbol in the “Check Pin” state indicates that the details of the sub-machine associated with “Check Pin” are specified in an another state machine

105
**Alternative Entry Points**

Sometimes, in a sub-machine, we do not want to start the execution from the initial state We want to start the execution from a “name alternative entry point” PerformActivity

106
**Alternative Entry Points**

Here’s the same system, from a higher level Transition from the “No Already Initialized” state leads to the standard initial state in the sub-machine Transition from the “Already Initialized” state is connected to the named alternative entry point “Skip Initializing”

107
**Alternative Exit Points**

It is also possible to have alternative exit points for a compound state Transition from “Processing Instructions” state takes the regular exit Transition from the “Reading Instructions” state takes an "alternative named exit point

108
**Use Case – Validate PIN (1)**

Use case name: Validate PIN Summary: System validates customer PIN Actor: ATM Customer Precondition: ATM is idle, displaying a Welcome message.

109
**Use Case – Validate PIN (2)**

Main sequence: Customer inserts the ATM card into the card reader. If system recognizes the card, it reads the card number. System prompts customer for PIN. Customer enters PIN. System checks the card's expiration date and whether the card has been reported as lost or stolen. If card is valid, system then checks whether the user-entered PIN matches the card PIN maintained by the system. If PIN numbers match, system checks what accounts are accessible with the ATM card. System displays customer accounts and prompts customer for transaction type: withdrawal, query, or transfer.

110
**Use Case – Validate PIN (3)**

Alternative sequences: Step 2: If the system does not recognize the card, the system ejects the card. Step 5: If the system determines that the card date has expired, the system confiscates the card. Step 5: If the system determines that the card has been reported lost or stolen, the system confiscates the card. Step 7: If the customer-entered PIN does not match the PIN number for this card, the system re-prompts for the PIN. Step 7: If the customer enters the incorrect PIN three times, the system confiscates the card. Steps 4-8: If the customer enters Cancel, the system cancels the transaction and ejects the card. Postcondition: Customer PIN has been validated.

111
ATM Machine Example Validate PIN:

112
ATM Machine Example Funds withdrawal:

113
Section 4 Behavioral Modeling

114
Topics We will continue to talk about UML State Machine We will go through a complete example of a simple software construction case study with emphasis on UML State Machines End this section with some final words of wisdom!

115
**Last Lecture We have talked about UML State Machines**

States and transitions State effects Self Transition Decision pseudo-states Compound states Alternative entry and exit points Today, we will tackle more advanced UML State Machines Concepts

116
History States A state machine describes the dynamic aspects of a process whose current behavior depends on its past A state machine in effect specifies the legal ordering of states a process may go through during its lifetime When a transition enters a compound state, the action of the nested state machine starts over again at its initial state Unless an alternative entry point is specified There are times you'd like to model a process so that it remembers the last substate that was active prior to leaving the compound state

117
**History States Simple washing machine state diagram:**

Power Cut event: transition to the “Power Off” state Restore Power event: transition to the active state before the power was cut off to proceed in the cycle

118
Concurrent Regions Sequential sub state machines are the most common kind of sub machines In certain modeling situations, concurrent sub machines might be needed (two or more sub state machines executing in parallel) Brakes example:

119
Concurrent Regions Example of modeling system maintenance using concurrent regions Maintenance Testing testingCompleted Testing devices Self diagnosing shutDown diagnosisCompleted Idle maintain Commanding commandProcessed [continue] Waiting Processing Command commandProcessed [not continue] command

120
Orthogonal Regions Concurrent Regions are also called Orthogonal Regions These regions allow us to model a relationship of “And” between states (as opposed to the default “or” relationship) This means that in a sub state machine, the system can be in several states simultaneously Let us analyse this phenomenon using an example of computer keyboard state machine

121
Keyboard Example (1) Keyboard example without Orthogonal Regions

122
Keyboard Example (2) Keyboard example with Orthogonal Regions

123
**Garage Door – Case Study**

Background Company DOORS inc. manufactures garage door components Nonetheless, they have been struggling with the embedded software running on their automated garage opener Motor Unit that they developed in house This is causing them to loose business They decided to scrap the existing software and hire a professional software company to deliver “bug free” software

124
**Client Requirements Client (informal) requirements:**

Requirement 1: When the garage door is closed, it must open whenever the user presses on the button of the wall mounted door control or the remote control Requirement 2: When the garage door is open, it must close whenever the user presses on the button of the wall mounted door control or the remote control Requirement 3: The garage door should not close on an obstacle Requirement 4: There should be a way to leave the garage door half open Requirement 5: System should run a self diagnosis test before performing any command (open or close) to make sure all components are functional

125
**Wall Mounted Controller**

Client Requirements Motor Unit (includes a microcontroller where the software will be running) Wall Mounted Controller (a remote controller is also supported) Sensor Unit(s) (detects obstacles, when the door is fully open and when it is fully closed)

126
**Use Case Diagram Use Case Diagram Garage Door System Open Door**

include Run Diagnosis Close Door Garage Door User include

127
**Run Diagnosis Use Case Use Case Name: Run Diagnosis**

Summary: The system runs a self diagnosis procedure Actor: Garage door user Pre-Condition: User has pressed the remote or wall mounted control button Sequence: Check if the sensor is operating correctly Check if the motor unit is operating correctly If all checks are successful, system authorizes the command to be executed Alternative Sequence: Step 3: One of the checks fails and therefore the system does not authorize the execution of the command Postcondition: Self diagnosis ensured that the system is operational

128
**Open Door Use Case Use Case Name: Open Door**

Summary: Open the garage the door Actor: Garage door user Dependency: Include Run Diagnosis use case Pre-Condition: Garage door system is operational and ready to take a command Sequence: User presses the remote or wall mounted control button Include Run Diagnosis use case If the door is currently closing or is already closed, system opens the door Alternative Sequence: Step 3: If the door is open, system closes door Step 3: If the door is currently opening, system stops the door (leaving it half open) Postcondition: Garage door is open

129
**Close Door Use Case Use Case Name: Close Door**

Summary: Close the garage the door Actor: Garage door user Dependency: Include Run Diagnosis use case Pre-Condition: Garage door system is operational and ready to take a command Sequence: User presses the remote or wall mounted control button Include Run Diagnosis use case If the door is currently open, system closes the door Alternative Sequence: Step 3: If the door is currently closing or is already closed, system opens the door Step 3: If the door is currently opening, system stops the door (leaving it half open) Postcondition: Garage door is closed

130
**High Level Behavioral Modeling**

131
**High Level Structural Model**

132
**Refined Structural Model**

133
**Refine Behavioral Model – Motor Unit**

Running Open buttonPressed() [isFunctioning()] Timer (180 s) [! isFunctioning()] Closing doorOpen() buttonPressed(), [! isFunctioning()] buttonPressed(), obstacleDetected() [isFunctioning()] doorClosed() WaitingForRepair Closed Timer (180 s) [isFunctioning()] buttonPressed() [isFunctioning()] Opening buttonPressed() buttonPressed() HalfOpen

134
**Refine Behavioral Model – Sensor Unit**

CheckingForObstacles SendingObstacleEvent [isObstacleDetected()] [!isObstacleDetected()] CheckingIfDoorOpen Time (20 ms) [isDoorOpen()] SendingOpenDoorEvent [!isDoorOpen()] CheckingIfDoorClosed SendingDoorClosedEvent [isDoorClosed()] [!isDoorClosed()] Sleeping

135
Do Not Fall Asleep yet!

136
Coding Whenever we are satisfied with the level of detail in our behavioral models, we can proceed to coding Some of the code can be generated directly by tools from the behavioral model Some tweaking might be necessary (do not use the code blindly) Humans are still the smartest programmers

137
Event Generator Class

138
Sensor Class

139
**State machine Implementation**

Sensor Class Sensor State machine Implementation

140
Umple Online Demo UMPLE is a modeling tool to enable what we call Model- Oriented Programming This is what we do in this course You can use it to create class diagrams (structural models) and state machines (behavioral models) The tool was developed at the university of Ottawa Online version can be found at: There’s also an eclipse plugin for the tool

141
**Umple Code For Motor Unit State Machine**

class Motor { status { Running { Open {buttonPressed[isFunctioning()]->Closing; } Closing { buttonPressed()[isFunctioning()]->Opening; ObstacleDetected()[isFunctioning()]->Opening; doorClosed()->Closed;} Closed { buttonPressed()[isFunctioning()]->Opening; } Opening { buttonPressed()->HalfOpen; doorOpen()->Open; } HalfOpen{buttonPressed()->Opening;} buttonPressed()[!isFunctioning()]->WaitingForRepair; } WaitingForRepair{ timer()[!isFunctioning()]->WaitingForRepair; timer()[isFunctioning()]->Running;}

142
**Motor Class Snippets Switching between high level states**

Switching between nest states inside the Running compound state

143
**When To Use State Machines?**

When an object or a system progresses through various stages of execution (states) The behavior of the system differs from one stage to another When you can identify clear events that change the status of the system They are ideal for event driven programming (less loops and branches, more events generated and exchanged) Lots of event are being exchanged between objects When using even driven programming Make sure you follow Observable or Event Notifier patterns Both are pretty simple (similar to what we have done for the garage door example)

144
**Behavioral Over-Modeling**

Please model responsibly!! Do not get carried out with modeling every single detail to the point where you run behind schedule You sell code, not models…

145
**Behavioral Over-Modeling**

Now, be careful, you do not want over-model Modern software development processes are all about only doing just enough modeling for a successful product Therefore, start with a high level model of the behavior This model should give a clear overview of some (not necessary all) of the important functionality of the system This would be similar to the first garage door state machine we created

146
**Behavioral Over-Modeling**

Identify potential complex areas that require further understanding We minimize the risk if we understand these components well before we start programing Model these complex areas in more details until you are satisfied that they are well understood Use tools to generate code from your existing models Do not rely blindly on tools (at least not yet!)

147
**Designing Classes with State Diagrams**

Keep the state diagram simple State diagrams can very quickly become extremely complex and confusing At all time, you should follow the aesthetic rule: “Less is More” If the state diagram gets too complex consider splitting it into smaller classes Think about compound states instead of a flat design

148
**Example of a CD Player with a Radio**

On Display Alarm Displaying Current Time Displaying Alarm Time Timer (3 s) Play CD Playing Radio Playing CD H Play Radio On On Off off

149
**More UML State Machines Examples**

Flight State Machine

150
**More UML State Machines Examples**

Flight State Machine Nested

151
**Section 5 Petri Nets These slides are Based on Lecture notes from:**

Dr. Chris Ling (http://www.csse.monash.edu.au/~sling/) SEG2106 – Winter 2014 – Hussein Al Osman

152
**Topics Today we will discuss another type of state machine:**

Petri nets (this will be just an introduction…) This will be the last behavioral modeling topic we cover We will start the next section of the course next week SEG2106 – Winter 2014 – Hussein Al Osman

153
Ok, let’s start… SEG2106 – Winter 2014 – Hussein Al Osman

154
**Introduction First introduced by Carl Adam Petri in 1962.**

A diagrammatic tool to model concurrency and synchronization in systems They allow us to quickly simulate complex concurrent behavior (which is faster than prototyping!) Fairly similar to UML State machines that we have seen so far Used as a visual communication aid to model the system behavior Based on strong mathematical foundation SEG2106 – Winter 2014 – Hussein Al Osman

155
**Example: POS Terminal (UML State Machine)**

(POS= Point of Sale) idle 1 digit d1 1 digit d2 1 digit 1 digit d3 d4 OK OK OK OK OK pressed Rejected Reject approve Approved SEG2106 – Winter 2014 – Hussein Al Osman

156
**Example: POS Terminal (Petri Net)**

1 digit 1 digit 1 digit 1 digit d4 Initial d1 d2 d3 OK OK OK OK OK pressed Rejected! approve Reject approved SEG2106 – Winter 2014 – Hussein Al Osman

157
**POS Terminal Scenario 1: Normal Enters all 4 digits and press OK.**

Scenario 2: Exceptional Enters only 3 digits and press OK. SEG2106 – Winter 2014 – Hussein Al Osman

158
**Example: POS System (Token Games)**

1 digit 1 digit 1 digit 1 digit d4 Initial d1 d2 d3 OK OK OK OK OK pressed Rejected! approve Reject approved SEG2106 – Winter 2014 – Hussein Al Osman

159
A Petri Net Components The terms are bit different than UML state machines Petri nets consist of three types of components: places (circles), transitions (rectangles) and arcs (arrows): Places represent possible states of the system Transitions are events or actions which cause the change of state (be careful, transitions are no longer arrows here) Every arc simply connects a place with a transition or a transition with a place. SEG2106 – Winter 2014 – Hussein Al Osman

160
Change of State A change of state is denoted by a movement of token(s) (black dots) from place(s) to place(s) Is caused by the firing of a transition. The firing represents an occurrence of the event or an action taken The firing is subject to the input conditions, denoted by token availability SEG2106 – Winter 2014 – Hussein Al Osman

161
Change of State A transition is firable or enabled when there are sufficient tokens in its input places. After firing, tokens will be transferred from the input places (old state) to the output places, denoting the new state SEG2106 – Winter 2014 – Hussein Al Osman

162
**Example: Vending Machine**

The machine dispenses two kinds of snack bars – 20c and 15c Only two types of coins can be used 10c coins and 5c coins (ah the old days!!) The machine does not return any change SEG2106 – Winter 2014 – Hussein Al Osman

163
**Example: Vending Machine (UML State Machine)**

Take 15c snack bar 15 cents inserted 5 cents inserted Deposit 10c Deposit 5c Deposit 5c 0 cent inserted Deposit 5c Deposit 5c Deposit 10c 20 cents inserted 10 cents inserted Deposit 10c Take 20c snack bar SEG2106 – Winter 2014 – Hussein Al Osman

164
**Example: Vending Machine (A Petri net)**

Take 15c bar Deposit 5c 0c Deposit 10c Deposit c 10c Deposit 20c 15c Take 20c bar SEG2106 – Winter 2014 – Hussein Al Osman

165
**Example: Vending Machine (3 Scenarios)**

Deposit 5c, deposit 5c, deposit 5c, deposit 5c, take 20c snack bar. Scenario 2: Deposit 10c, deposit 5c, take 15c snack bar. Scenario 3: Deposit 5c, deposit 10c, deposit 5c, take 20c snack bar. SEG2106 – Winter 2014 – Hussein Al Osman

166
**Example: Vending Machine (Token Games)**

Take 15c bar Deposit 5c 0c Deposit 10c Deposit c 10c Deposit 20c 15c Take 20c bar SEG2106 – Winter 2014 – Hussein Al Osman

167
Multiple Local States In the real world, events happen at the same time A system may have many local states to form a global state. There is a need to model concurrency and synchronization SEG2106 – Winter 2014 – Hussein Al Osman

168
**Example: In a Restaurant (A Petri Net)**

Waiter free Customer 1 Customer 2 Take order Take order wait Order taken wait eating eating Tell kitchen Serve food Serve food SEG2106 – Winter 2014 – Hussein Al Osman

169
**Example: In a Restaurant (Two Scenarios)**

Waiter Takes order from customer 1 Serves customer 1 Takes order from customer 2 Serves customer 2 Scenario 2: SEG2106 – Winter 2014 – Hussein Al Osman

170
**Example: In a Restaurant (Scenario 2)**

Waiter free Customer 1 Customer 2 Take order Order taken Tell kitchen wait Serve food eating SEG2106 – Winter 2014 – Hussein Al Osman

171
**Example: In a Restaurant (Scenario 1)**

Waiter free Customer 1 Customer 2 Take order Order taken Tell kitchen wait Serve food eating SEG2106 – Winter 2014 – Hussein Al Osman

172
**Net Structures A sequence of events/actions: Concurrent executions: e1**

SEG2106 – Winter 2014 – Hussein Al Osman

173
Net Structures Non-deterministic events - conflict, choice or decision: A choice of either e1, e2 … or e3, e4 ... e1 e2 e3 e4 SEG2106 – Winter 2014 – Hussein Al Osman

174
**Net Structures Synchronization e1**

SEG2106 – Winter 2014 – Hussein Al Osman

175
**Net Structures Synchronization and Concurrency e1**

SEG2106 – Winter 2014 – Hussein Al Osman

176
**Another Example A producer-consumer system, consist of:**

One producer Two consumers One storage buffer With the following conditions: The storage buffer may contain at most 5 items; The producer sends 3 items in each production; At most one consumer is able to access the storage buffer at one time; Each consumer removes two items when accessing the storage buffer SEG2106 – Winter 2014 – Hussein Al Osman

177
**A Producer-Consumer System**

k=2 k=1 accepted ready p1 p4 Storage p3 produce accept 3 2 t1 t2 t3 t4 consume send k=5 p2 p5 idle ready k=1 k=2 Producer Consumers SEG2106 – Winter 2014 – Hussein Al Osman

178
**A Producer-Consumer Example**

In this Petri net, every place has a capacity and every arc has a weight. This allows multiple tokens to reside in a place to model more complex behavior. SEG2106 – Winter 2014 – Hussein Al Osman

179
**Short Break? Are you here yet?**

SEG2106 – Winter 2014 – Hussein Al Osman

180
**Behavioral Properties**

Reachability “Can we reach one particular state from another?” Boundedness “Will a storage place overflow?” Liveness “Will the system die in a particular state?” SEG2106 – Winter 2014 – Hussein Al Osman

181
**Recalling the Vending Machine (Token Game)**

Take 15c bar Deposit 5c 0c Deposit 10c Deposit c 10c Deposit 20c 15c Take 20c bar SEG2106 – Winter 2014 – Hussein Al Osman

182
**A marking is a state ... M0 = (1,0,0,0,0) M1 = (0,1,0,0,0)**

p4 M0 = (1,0,0,0,0) t4 M1 = (0,1,0,0,0) p2 t1 M2 = (0,0,1,0,0) M3 = (0,0,0,1,0) p1 M4 = (0,0,0,0,1) t3 t7 t5 Initial marking:M0 t6 p5 t2 p3 t9 SEG2106 – Winter 2014 – Hussein Al Osman

183
**Reachability p1 t8 t1 t2 p2 t3 p3 t4 t5 t6 p5 t7 p4 t9**

Initial marking:M0 M0 = (1,0,0,0,0) M1 = (0,1,0,0,0) M2 = (0,0,1,0,0) M3 = (0,0,0,1,0) M4 = (0,0,0,0,1) M0 M1 M2 M3 M4 t3 t1 t5 t8 t2 t6 SEG2106 – Winter 2014 – Hussein Al Osman

184
**Reachability A firing or occurrence sequence:**

“M2 is reachable from M1 and M4 is reachable from M0.” In fact, in the vending machine example, all markings are reachable from every marking. M0 M1 M2 M3 M4 t3 t1 t5 t8 t2 t6 A firing or occurrence sequence: SEG2106 – Winter 2014 – Hussein Al Osman

185
Boundedness A Petri net is said to be k-bounded or simply bounded if the number of tokens in each place does not exceed a finite number k for any marking reachable from M0. The Petri net for vending machine is 1-bounded. SEG2106 – Winter 2014 – Hussein Al Osman

186
Liveness A Petri net with initial marking M0 is live if, no matter what marking has been reached from M0, it is possible to ultimately fire any transition by progressing through some further firing sequence. A live Petri net guarantees deadlock-free operation, no matter what firing sequence is chosen. SEG2106 – Winter 2014 – Hussein Al Osman

187
Liveness The vending machine is live and the producer-consumer system is also live. A transition is dead if it can never be fired in any firing sequence. SEG2106 – Winter 2014 – Hussein Al Osman

188
**An Example A bounded but non-live Petri net t1 p3 t3 t4 p1 p2 p4 t2**

SEG2106 – Winter 2014 – Hussein Al Osman

189
**Another Example An unbounded but live Petri net M0 = (1, 0, 0, 0, 0)**

SEG2106 – Winter 2014 – Hussein Al Osman

190
**Other Types of Petri Nets**

Object-Oriented Petri nets Tokens can either be instances of classes, or states of objects. Net structure models the inner behaviour of objects. SEG2106 – Winter 2014 – Hussein Al Osman

191
**An O-O Petri Net Producer Consumer Producer Consumer**

accepted ready Storage accept produce send consume ready Producer state: ProducerState Item produce( ) send(i: Item): void Consumer state: ConsumerState accept( i: Item): void consume(i: Item) : void SEG2106 – Winter 2014 – Hussein Al Osman

192
Petri Net References Murata, T. (1989, April). Petri nets: properties, analysis and applications. Proceedings of the IEEE, 77(4), Peterson, J.L. (1981). Petri Net Theory and the Modeling of Systems. Prentice-Hall. Reisig, W and G. Rozenberg (eds) (1998). Lectures on Petri Nets 1: Basic Models. Springer-Verlag. The World of Petri nets: SEG2106 – Winter 2014 – Hussein Al Osman

193
**Introduction to Compilers**

Section 6 Introduction to Compilers

194
**Topics Natural languages Lexemes or lexical entities**

Syntax and semantics Computer languages Lexical analysis Syntax analysis Semantic analysis Compilers Compiler’s basic requirements Compilation process

195
**Natural Languages Basics**

In a (natural) language: A sentence is a sequence of words A word (also called lexemes of lexical units) is a sequence of characters (possibly a single one) The set of characters used in a language is finite (know as the alphabet) The set of possible sentences in a language is infinite A dictionary lists all the words (lexemes) of a language The words are classified into different lexical categories: verb, noun, pronoun, preposition….

196
**Natural Languages Basics**

A grammar (also considered the set of syntax rules) to determine which sequences of words are well formed Sequences must have a structure that obeys the grammatical rules Well formed sentences, usually have a meaning that humans understand We are trying to teach our natural languages to machines With mixed results!!

197
Analysis of Sentences Lexical Analysis: identification of words made up of characters Words are classified into several categories: articles, nouns, verbs, adjectives, prepositions, pronouns… Syntax analysis: rules for combining words to form sentences Analysis of meaning: difficult to formalize Easily done by humans Gives machines a hard time (although natural language processing is evolving) Big research field for those interested in graduate studies…

198
**Computer Language Processing**

In computer (or programming) languages, one speaks about a program (corresponding to a long sentence or paragraph) Sequence of lexical units or lexemes Lexical units are sequences of characters Lexical rules of the language determine what the valid lexical units of the language are There are various lexical categories: identifier, number, character string, operator… Lexical categories are also known as tokens

199
**Computer Language Processing**

Syntax rules of the language determine what sequences of lexemes are well-formed programs Meaning of a well-formed program is also called its semantics A program can be well-formed, but its statements are nonsensical Example: int x = 0; x = 1; x = 0; Syntactically, the above code is valid, but what does it mean??

200
**Computer Language Processing**

Compilers should catch and complain about lexical and syntax errors Compilers might complain about common semantic errors: public boolean test (int x){ boolean result; if (x > 100) result = true; return result; } Your coworkers or the client will complain about the rest!! Error message: The local variable result may have not been initialized

201
**Compilers What is a compiler?**

Program that translates an executable program in one language into an executable program in another language We expect the program produced by the compiler to be better, in some way, than the original What is an interpreter? Program that reads an executable program and produces the results of running that program We will focus on compilers in this course (although many of the concepts apply to both)

202
**Basic Requirements for Compilers**

Must-Dos: Produce correct code (byte code in the case of Java) Run fast Output must run fast Achieve a compile time proportional to the size of the program Work well with debuggers (absolute must) Must-Haves: Good diagnostics for lexical and syntax errors Support for cross language calls (checkout Java Native Interface if you are interested)

203
**Abstract View of Compilers**

A compiler usually realizes the translation in several steps; correspondingly, it contains several components. Usually, a compiler includes (at least) separate components for verifying the lexical and syntax rules:

204
**Intermediate Code Generator**

Compilation Process Source Program Lexical Analyser Syntax Analyser Semantic Analyser Intermediate Code Generator Code Optimizer Code Generator Machine Code

205
Compilation Process More than one course is required to cover the details of the various phases In this course, we will scratch the surface We will focus on lexical and syntax analysis

206
**Some Important Definitions**

These definitions, although sleep inducing, are important in order to understand the concepts that will be introduced in the next lectures So here we go…

207
Alphabet Recall from beginning of the lecture (or kindergarten): an alphabet is the set of characters that can be used to form a sentence Since mathematicians love fancy Greek symbols, we will refer to an alphabet as …

208
**Alphabet is an alphabet, or set of terminals**

Finite set and consists of all the input characters or symbols that can be arranged to form sentences in the language English: A to Z, punctuation and space symbols Programming language: usually some well-defined computer set such as ASCII

209
**Strings of Terminals in An Alphabet**

={a,b,c,d} Possible strings of terminals from include aaa aabbccdd d cba abab ccccccccccacccc Although this is fun, I think you get the idea…

210
Formal Languages : alphabet, it is a finite set consisting of all input characters or symbols *: closure of the alphabet, the set of all possible strings in , including the empty string A (formal) language is some specified subset of *

211
Section 7 Lexical Analysis

212
Topics The role of the lexical analyzer Specification of tokens Finite state machines From a regular expressions to an NFA

213
**The Role of Lexical Analyzer**

Lexical analyzer is the first phase of a compiler Task: read input characters and produce a sequence of tokens that the parser uses for syntax analysis Remove white spaces token Lexical Analyser (scanner) Syntax Analyser (parser) Source Program Get next token

214
Lexical Analysis There are several reasons for separating the analysis phase of compiling into lexical analysis and syntax analysis (parsing): Simpler (layered) design Compiler efficiency Specialized tools have been designed to help automate the construction of both separately

215
Lexemes Lexeme: sequence of characters in the source program that is matched by the pattern for a token A lexeme is a basic lexical unit of a language Lexemes of a programming language include its Identifiers: names of variables, methods, classes, packages and interfaces… Literals: fixed values (e.g. “1”, “17.56”, “0xFFE” …) Operators: for Maths, Boolean and logical operations (e.g. “+”, “-”, “&&”, “|” …) Special words: keywords (e.g. “if”, “for”, “public” …)

216
**Tokens, Patterns, Lexemes**

Token: category of lexemes A pattern is a rule describing the set of lexemes that can represent as particular token in source program

217
**The substring pi is a lexeme for the token “identifier.”**

Examples of Tokens double pi = ; The substring pi is a lexeme for the token “identifier.” Token Sample Lexemes Informal Description of Pattern type double if booelan_operator <. <=, ==, >, >= < or <= or == or > or >= id pi, count, d2 Letter followed by letters and digits literal 3.1414, “test” Any alpha numeric string of characters

218
**Lexeme and Token (more detailed Categories)**

Index = 2 * count +17; semicolon ; int_literal 17 plus_op + variable Count multi_op * 2 equal_sign = Index Tokens Lexemes

219
**Lexical Errors Few errors are discernible at the lexical level alone**

Lexical analyzer has a very localized view of a source program Let some other phase of compiler handle any error

220
**Specification of Tokens**

We need a powerful notation to specify the patterns for the tokens Regular expressions to the rescue!! In process of studying regular expressions, we will discuss: Operation on languages Regular definitions Notational shorthands

221
Recall: Languages : alphabet, it is a finite set consisting of all input characters or symbols *: closure of the alphabet, the set of all possible strings in , including the empty string A (formal) language is some specified subset of *

222
**Operations on Languages**

223
**Operations on Languages**

Non-mathematical format: Union between languages L and M: the set of strings that belong to at least one of both languages Concatenation of languages L and M: the set of all strings of the form st where s is a string from L and t is a string from M Intersection between languages L and M: the set of all strings which are contained in both languages Kleene closure (named after Stephen Kleene): the set of all strings that are concatenations of 0 or more strings from the original language Positive closure : the set of all strings that are concatenations of 1 or more strings from the original language

224
Regular Expressions Regular expression is a compact notation for describing string. In Java, an identifier is a letter followed by zero or more letter or digits letter (letter | digit)* |: or *: zero or more instance of

225
Rules is a regular expression that denotes {}, the set containing empty string If a is a symbol in , then a is a regular expression that denotes {a}, the set containing the string a Suppose r and s are regular expressions denoting the language L and M, then (r) |(s) is a regular expression denoting LM. (r)(s) is regular expression denoting LM (r) * is a regular expression denoting (L)*.

226
**Precedence Conventions**

The unary operator * has the highest precedence and is left associative. Concatenation has the second highest precedence and is left associative. | has the lowest precedence and is left associative. (a)|(b)*(c)a|b*c

227
**Example of Regular Expressions**

228
**Properties of Regular Expression**

229
Regular Definitions If is an alphabet of basic symbols, then a regular definition is a sequence of definitions of the form: d1 r1 d2 r2 ... dn rn Where each di is a distinct name, and each ri is a regular expression over the symbols in {d1,d2,…,di-1}, i.e., the basic symbols and the previously defined names.

230
**Example of Regular Definitions**

231
**Notational Shorthands**

Certain constructs occur so frequently in regular expressions that it is convenient to introduce notational short hands for them We have already seen some of these short hands: One or more instances: a+ denotes the set of all strings of one or more a’s Zero or more instances: a* denotes all the strings of zero or more a’s Character classes: the notation [abc] where a, b and c denotes the regular expresssion a | b | c Abbreviated character classes: the notation [a-z] denotes the regular expression a | b | …. | z

232
**Notational Shorthands**

Using character classes, we can describe identifiers as being strings described by the following regular expression: [A-Za-z][A-Za-z0-9]*

233
Finite State Automata Now that we have learned about regular expressions How can we tell if a string (or lexeme) follows a regular expression pattern or not? We will again use state machines! This time, they are not UML state machines or petri nets We will call them: Finite Automata The program that executes such state machines is called a Recognizer

234
Short Break…

235
Finite Automata A recognizer for a language is a program that takes as input a string x and answers “Yes” if x is a lexem of the language “No” otherwise We compile a regular expression into a recognizer by constructing a generalized transition diagram called a finite automaton A finite automaton can be deterministic or nondeterministic Nondeterministic means that more than one transition out of a state may be possible on the same input symbol

236
**Nondeterministic Finite Automata (NFA)**

A set of states S A set of input symbols that belong to alphabet A set of transitions that are triggered by the processing of a character A single state s0 that is distinguished as the start (initial) state A set of states F distinguished as accepting (final) states.

237
**Example of an NFA The following regular expression (a|b)*abb**

Can be described using an NFA with the following diagram:

238
Example of an NFA The previous diagram can be described using the following table as well Remember the regular expression was: (a|b)*abb

239
**Another NFA example NFA accepting the following regular expression:**

aa*|bb*

240
**Deterministic Finite Automata (DFA)**

A DFA is a special case of a NFA in which No state has an -transition For each state s and input symbol a, there is at most one edge labeled a leaving s

241
Another DFA Example For the same regular expression we have seen before (a|b)*abb

242
NFA vs DFA Always with the regular expression: (a|b)*abb NFA: DFA:

243
Example of a DFA Recognizer for identifier:

244
**Tables for the Recognizer**

To change regular expression, we can simply change tables…

245
**Code for the Recognizer**

246
Section 8 Finite State Automata

247
Topics Algorithm to create NFAs from regular expressions Algorithm to convert from NFA to DFA Algorithm to minimize DFA Many examples….

248
**Creating Deterministic Finite Automata (DFA)**

In order to create a DFA, we have to perform the following: Create a Non-deterministic Finite Automata (NFA) out of the regular expression Convert the NFA into a DFA

249
**NFA Creation Rules A | B AB A* A B 2 3 4 5 1 6 ε 1 2 A B 3 ε 2 3 ε 4 1**

250
**NFA Creation Examples y z 1 x 2 3 4 6 ε 5 7**

x | yz According to precedence rules, this is equivalent to: x | (yz) This has the same form as A | B: And B can be represented as: Putting all together: 1 6 A B 2 3 4 5 ε 1 2 y z 3 y z 1 x 2 3 4 6 ε 5 7

251
**NFA Creation Examples (x | y)* We have seen A*: Therefore, (x | y)*: ε**

8 1 2 7 x y 3 4 5 6

252
NFA Creation Examples abb

253
NFA Creation Examples a*bb 2 3 ε 4 1 a 5 b 6

254
NFA Creation Examples (a|b)*bc ε 7 1 6 a b 2 3 4 5 c 8 9

255
**Conversion of an NFA into DFA**

Subset construction algorithm is useful for simulating an NFA by a computer program In the transition table of an NFA, each entry is a set of states In the transition table of a DFA, each entry is just a single state. General idea behind the NFA-to-DFA conversion: each DFA state corresponds to a set of NFA states

256
**Subset Construction Algorithm**

Algorithm: Subset Construction - Used to construct a DFA from an NFA Input: An NFA “N” Output: A DFA “D” accepting the same language

257
**Subset Construction Algorithm**

Method: Let s be a state in “N” and “T” be a set of states, and using the following operations:

258
**Subset Construction (Main Algorithm)**

259
**Subset Construction (ε-closure computation)**

260
**Conversion Example Regular Expression: (x | y)* Dstates={A,B,C}, where**

ε 8 1 2 7 x y 3 4 5 6 Regular Expression: (x | y)* Dstates={A,B,C}, where A = (1,2,3,5,8) B = (2,3,4,5,7,8) C = (2,3,5,6,7,8) x y A B C

261
Conversion Example Regular Expression: (x | y)* x A B C y x y A B C

262
**Another Conversion Example**

Regular Expression: (a | b)*abb

263
**Another Conversion Example**

Regular Expression: (a | b)*abb

264
**Another Conversion Example**

Regular Expression: (a | b)*abb

265
**Minimizing the number of states in DFA**

Minimize the number of states of a DFA by finding all groups of states that can be distinguished by some input string Each group of states that cannot be distinguished is then merged into a single state

266
**Minimizing the number of states in DFA**

Algorithm: Minimizing the number of states of a DFA Input: A DFA “D” with a set of states S Output: A DFA “M” accepting the same language as “D” yet having as few states as possible

267
**Minimizing the number of states in DFA**

Method: Construct an initial partition Π of the set of states with two groups: The accepting states group All other states group Partition Π to Πnew (using the procedure shown on the next slide) If Πnew != Π, repeat step (2). Otherwise, repeat go to step (4) Choose one state in each group of the partition Π as the representative of the group Remove dead states

268
**Construct New Partition Procedure**

for each group G of Π do begin Partition G into subgroups such that two states s and t of G are in the same subgroup if and only if for all input symbols a, states s and t have transitions on a to states in the same group of Π; /* at worst, a state will be in a subgroup by itself*/ Replace G in Πnew by the set of all subgroups formed end

269
**Example of NFA Minimization**

B C a D A c E F b Π= A B, C, D, E F A B, C, D, E F A, B, C, D, E F

270
**Example of NFA Minimization**

Minimized DFA, where: 1: A 2: B, C, D, E 3: F 2 1 c a 3 b

271
**Practical Regular Expressions**

Section 9 Practical Regular Expressions

272
Topics Practical notations that are often used with regular expression Few practice exercises

273
**Practical Regular Expressions Tricks**

We will see practical regular expressions tricks that are supported by most regex libraries Remember, regular expressions are not only used in the context of compilers We often use them to extract information from text Example: imagine looking in a log file that has been accumulating entries for the past two months for a particular error pattern Without regular expressions, this would be a tedious job Sooner or later, when you work in the industry, you will encounter such issues regular expressions will come in handy

274
Matching Digits To match a single digit, as we have seen before, we can use the following regular expression: [0-9] Nonetheless, since matching a digit is a common operation, we can use the following notation: \d Slash is an escape character used to distinguish it from the letter d Similarly, to match a non-digit character, we can use the notation: \D

275
**Alphanumeric Characters**

To match an alphanumeric character, we can use the notation: [a-zA-Z0-9] Or we can use the following shortcut \w Similarly, we can represent any non-alphanumeric character as follows: \W

276
Wildcard A wildcard is defined to match any single character (letter, digit, whitespace …) It is represented by the . (dot) character Therefore, in order to match a dot, you have to use the escape character: \.

277
**Exclusion We have seen that [abc] is equivalent to (a | b | c)**

But sometimes we want to match everything except a set of characters To achieve this, we can use the notation: [^abc] This matches any single character other than a, b or c This notation can also be used with abbreviated character classes [^a-z] matches any character other than a small letter

278
Repetitions How can we match a letter or a string that repeats several times in a row: E.g. ababab So far, we have implemented repetitions through three mechanisms: Concatenation: simply concatenate the string or character with itself (does not work if you do not know the exact number of repetitions) Kleene star closure: to match letters or strings repeated 0 or more times Positive closure: to match letters or strings repeated 1 or more times

279
Repetitions We can also specify a range of how many times a letter or string can be repeated Example, if we want to match strings of repetition of the letter a between 1 and 3 times, we can use the notation: a {1,3} Therfore, a {1,3} matches the string aaa We can also specify an exact number of repetitions instead of a range ab {3} matches the string ababab

280
Optional Characters The concept of the optional character is somewhat similar to that of the kleene star The star operator matches 0 or more instances of the operand The optional operator, denoted as ? (question mark), matches 0 or one instances of the operand Example: the pattern ab?c will match either the strings "abc" or "ac" because the b is considered optional.

281
**White Space Often, we want to easily detect white spaces**

Either to remove them or to detect the beginning or end of words Most common forms of whitespace used with regular expressions: Space _, the tab \t, the new line \n and the carriage return \r A whitespace special character \s will match any of the specific whitespaces above Similarly, you can match any non-white space character using the notation \S

282
**Few Exercises Given the sentence: Error, computer will not shut down…**

Provide a regular expression that will match all the words in the sentence Answer: \w*

283
**Few Exercises Given the sentence: Error, computer will not shut down…**

Provide a regular expression that will match all the non- alphanumeric characters Answer: \W*

284
**Few Exercises Given the log file:**

[Sunday Feb ] Program starting up [Monday Feb ] Entered initialization phase [Tuesday Feb ] Error 5: cannot open XML file [Thursday Feb ] Warning 5: response time is too slow [Friday Feb ] Error 9: major error occurred, system will shut down Match any error or warning message that ends with the term “shut down” Answer: (Error|Warning).*(shut down)

285
**Few Exercises Given the log file:**

[Sunday Feb ] Program starting up [Monday Feb ] Entered initialization phase [Tuesday Feb ] Error 5: cannot open XML file [Thursday Feb ] Warning 5: response time is too slow [Friday Feb ] Error 9: major error occurred, system will shut down Match any Error or Warning before between 1 and 6th February Answer: \[\w* Feb\. [1-6] 2014\] (Error|Warning)

286
**Introduction to Syntax Analysis**

Section 10 Introduction to Syntax Analysis

287
Topics Context free grammars Derivations Parse Trees Ambiguity Top-down parsing Left recursion

288
The Role of Parser

289
**Context Free Grammars A Context Free Grammar (CFG) consists of**

Terminals Nonterminals Start symbol Productions A language that can be generated by a grammar is said to be a context-free language

290
Context Free Grammars Terminals: are the basic symbols from which strings are formed These are the tokens that were produced by the Lexical Analyser Nonterminals: are syntactic variables that denote sets of strings One nonterminal is distinguished as the start symbol The productions of a grammar specify the manner in which the terminal and nonterminals can be combined to form strings

291
Example of Grammar The grammar with the following productions defines simple arithmetic expressions 〈expr〉 ::= 〈expr〉 〈op〉 〈expr〉 〈expr〉 ::= id 〈expr〉 ::= num 〈op〉 ::= + 〈op〉 ::= - 〈op〉 ::= * 〈op〉 ::= / In this grammar, the terminal symbols are num, id + - * / The nonterminal symbols are 〈expr〉 and 〈op〉, and 〈expr〉 is the start symbol

292
Derivations 〈expr〉 〈expr〉〈op 〉〈expr〉 is read “expr derives expr op expr” 〈expr〉 〈expr〉〈op 〉〈expr〉 id 〈op 〉〈expr〉 id *〈expr〉 id*id is called a derivation of id*id from expr.

293
Derivations If A::= is a production and and are arbitrary strings of grammar symbols, we can say: A If 12... n, we say 1 derives n.

294
**Derivations means “derives in one step.”**

means “derives in zero or more steps.” if and then means “derives in one or more steps.” If S , where may contain nonterminals, then we say that is a sentential form If does no contains any nonterminals, we say that is a sentence * * * + *

295
**Derivations G: grammar S: start symbol**

L(G): the language generated by G Strings in L(G) may contain only terminal symbols of G A string of terminals w is said to be in L(G) if and only if Sw The string w is called a sentence of G A language that can be generated by a grammar is said to be a context-free language If two grammars generate the same language, the grammars are said to be equivalent +

296
**Derivations We have already seen the following production rules:**

〈expr〉 ::= 〈expr〉〈op〉〈expr〉| id | num 〈op〉 ::= + | - | * | / The string id+id is a sentence of the above grammar because 〈expr〉 〈expr〉+〈expr〉 id +〈expr〉 id + id We write 〈expr〉 id+id *

297
Parse Tree expr expr op id + id This is called: Leftmost derivation

298
Two Parse Trees Let us again consider the arithmetic expression grammar. For the line of code: x+2*y (we are not considering the semi colon for now) Lexical Analyser Syntax Analyser x+z*y id+id*id parse tree Grammar: 〈expr〉::=〈expr〉〈op〉〈expr〉| id | num 〈op〉::= + | - | * | /

299
Two Parse Trees Let us again consider the arithmetic expression grammar. The sentence id + id * id has two distinct leftmost derivations: 〈expr〉 〈expr〉〈op〉〈expr〉 id 〈op〉〈expr〉 id +〈expr〉 id +〈expr〉〈op〉〈expr〉 id + id〈op〉〈expr〉 id + id *〈expr〉 id + id * id 〈expr〉 〈expr〉〈op〉〈expr〉 〈expr〉〈op〉〈expr〉〈op〉〈expr〉 id〈op〉〈expr〉〈op〉〈expr〉 id +〈expr〉〈op〉〈expr〉 id + id〈op〉〈expr〉 id + id *〈expr〉 id + id * id Grammar: 〈expr〉::=〈expr〉〈op〉〈expr〉| id | num 〈op〉::= + | - | * | /

300
**Two Parse Trees 〈expr〉::=〈expr〉〈op〉〈expr〉| id | num**

+ expr op expr op * id id * id id + id Equivalent to: id+(id*id) Equivalent to: (id+id)*id Grammar: 〈expr〉::=〈expr〉〈op〉〈expr〉| id | num 〈op〉::= + | - | * | /

301
**Precedence The previous example highlights a problem in the grammar:**

It does not enforce precedence It has not implied order of evaluation We can expand the production rules to add precedence

302
**Applying Precedence Update**

The sentence id + id * id has only one leftmost derivation now: expr term expr + 〈expr〉 〈expr〉 +〈term〉 〈term〉 +〈term〉 〈factor〉+〈term〉 id +〈term〉 id +〈term〉*〈factor〉 id +〈factor〉*〈factor〉 id + id *〈factor〉 id + id * id term term factor * factor factor id id id Grammar: 〈expr〉 ::=〈expr〉+ 〈term〉|〈expr〉- 〈term〉| 〈term〉 〈term〉 ::=〈term〉*〈factor〉| 〈term〉/〈factor〉|〈factor〉 〈factor〉 ::= num | id

303
Ambiguity A grammar that produces more than one parse tree for some sentence is said to be ambiguous. Example: Consider the following statement: It has two derivations It is a context free ambiguity

304
Ambiguity A grammar that produces more than one parse tree for some sentence is said to be ambiguous

305
**Eliminating Ambiguity**

Sometimes an ambiguous grammar can be rewritten to eliminate the ambiguity. E.g. “match each else with the closest unmatched then” This is most likely the intention of the programmer

306
**Mapping this to a Java Example**

In Java, the grammar rules are slightly different then the previous example Below is a (very simplified) version of these rules <stmnt> ::= <matched> | <unmatched> <matched> ::= if ( <expr> ) <matched> else <matched> | other stmnts <unmatched> ::= if ( <expr> ) < stmnt > | if ( <expr> ) <matched> else <unmatched>

307
**Mapping this to a Java Example**

For the following piece of code if (x==0) if (y==0) z = 0; else z = 1; After running the lexical analyser, we get the following list of tokens: if ( id == num ) if (id == num) id = num ; else id = num ;

308
**Mapping this to a Java Example**

Token input string: if ( id == num ) if (id == num) id = num ; else id = num ; Building the parse tree: stmnt umatched ( ) expr stmnt if matched ( ) expr matched if else

309
**Mapping this to a Java (Another) Example**

Token input string: if ( id == num ) else id = num ; Building the parse tree: ( ) expr matched if else stmnt

310
Top Down Parsing A top-down parser starts with the root of the parse tree, labelled with the start or goal symbol of the grammar To build a parse tree, we repeat the following steps until the leafs of the parse tree matches the input string At a node labelled A, select a production A::=α and construct the appropriate child for each symbol of α When a terminal is added to the parse tree that does not match the input string, backtrack Find the next nonterminal to be expanded

311
Top Down Parsing Top-down parsing can be viewed as an attempt to find a leftmost derivation for an input string Example: Grammar: <S> ::= c<A>d <A> ::= ab | a Input string cad We need to backtrack!

312
Expression Grammar Recall our grammar for simple expressions: Consider the input string: id – num * id

313
Example Reference Grammar

314
**Example Another possible parse for id – num * id**

If the parser makes the wrong choices, expansion does not terminate This is not a good property for a parser to have Parsers should terminate, eventually…

315
**Top down parses cannot handle left- recursion in a grammar**

A grammar is left recursive if: “It has a nonterminal A such that there is a derivation AA for some string ” Top down parses cannot handle left- recursion in a grammar +

316
**Eliminating Left Recursion**

Consider the grammar fragment: Where α and β do not start with 〈foo〉 We can re-write this as: Where 〈bar〉is a new non-terminal This Fragment contains no left recursion

317
**Example Our expression grammar contains two cases of left-recursion**

Applying the transformation gives With this grammar, a top-down parser will Terminate (for sure) Backtrack on some inputs

318
Predictive Parsers We saw that top-down parsers may need to backtrack when they select the wrong production Therefore, we might need predictive parsers to avoid backtracking This is where predictive parsers come in useful LL(1): left to right scan, left-most derivation, 1-token look ahead LR(1): left to right scan, right most derivation, 1-token look ahead

319
Section 11 LL(1) Parser

320
Topics LL(1) Grammar Eliminating Left Recursion Left Factoring FIRST and FOLLOW sets Parsing tables LL(1) parsing Many examples…

321
Review: Role of Parser

322
Predictive Parsers We saw that top-down parsers may need to backtrack when they select the wrong production We want to avoid backtracking This is where predictive parsers come in useful LL(1): left to right scan, left-most derivation, 1-token look ahead LR(1): left to right scan, right most derivation, 1-token look ahead

323
LL(1) Grammar In order to use LL(1) parsers, the Context-Free Grammar has to be: Unambiguous (we have discussed ambiguity before) Without left recursion (we have discussed left recursion elimination before) Left factored (we will discuss left factoring today) Ambiguity Removal Left Recursion Removal Left Factoring LL(1) Grammar CFG The above methods will convert many grammars to LL(1) form, but not all… There exit many exceptions.

324
**Review: Left Recursion**

A grammar is left recursive if: “It has a nonterminal A such that there is a derivation AA for some string ” Top down parses cannot handle left- recursion in a grammar +

325
**Eliminating Left Recursion**

Consider the grammar fragment: Where α and β do not start with 〈foo〉 We can re-write this as: Where 〈bar〉is a new non-terminal This Fragment contains no left recursion

326
**For a terminal w, we can say:**

Left Factoring For any two productions Aα | β, we would like a distinct way of choosing the correct production to expand We define FIRST(α) as the set of terminals that appear first in some string derived from α For a terminal w, we can say: w ∈ FIRST(α) iff α wz *

327
Left Factoring Now going back to our two productions: Aα and Aβ, we would like: FIRST(α) ∩ FIRST(β) = f This would allow the parser to make a correct choice with a look ahead of only one symbol

328
**FIRST(1) ∩ FIRST(2) ∩ FIRST(3) ≠ f**

Left Factoring Given this grammar: The parser cannot choose between productions 1, 2 and 3 given an input token of num or id FIRST(1) ∩ FIRST(2) ∩ FIRST(3) ≠ f Left factoring is required to solve this problem! 1 2 3 4 5 6 7 8

329
**Left Factoring So how does it work?**

For each non-terminal A, find the longest prefix α common to two or more of its alternatives If α ≠ ε, then replace all of the A productions A αβ1| αβ2| αβ3| … | αβn With A α A’ A’β1| β2| β3| … | βn Where A’ is a new non-terminal Repeat until no two alternatives for a single non-terminal have a common prefix

330
Left Factoring Therefore, in our grammar: When we perform the left factoring (on expr and term), we get:

331
Short Break Imagine, you are not in class, but on the beach, and I do not exist… Doesn’t that feel good!!

332
**Left Recursion Removal**

LL(1) Parser So we now know how to take a Context-Free Grammar, and transform it into an LL(1) grammar (at least we can try…) Ambiguity Removal Left Recursion Removal Left Factoring LL(1) Grammar CFG

333
LL(1) Parser We need to implement an LL(1) parser that can analyse the syntax of an input string of tokens without backtracking Of course given that the grammar is compatible with such parser In order to do that, we need to find two sets for each non- terminal: FIRST (we have briefly discussed this set earlier) FOLLOW

334
**FIRST(A)[FIRST(B)- ε] υ FIRST(α)**

FIRST Set Calculation Rules to calculate the FIRST set: FIRST(terminal){terminal} If Aaα, and a is a terminal: FIRST(A){a} If ABα, and rule Bε does NOT exist: FIRST(A)FIRST(B) If ABα, and rule Bε DOES exist: FIRST(A)[FIRST(B)- ε] υ FIRST(α)

335
**FIRST(A)[FIRST(B)- ε] υ FIRST(α)**

FIRST Set Calculation Let’s apply these rules to an example. Given the grammar: <S> ::= <A><B> <A> ::= a <B> ::= b FIRST(A) = {a} (applying 2nd rule) FIRST(B) = {b} (applying 2nd rule) FIRST(S) = FIRST(A) = {a} (applying 3rd rule) 1) FIRST(terminal){terminal} 2) If Aaα, and a is a terminal: FIRST(A){a} 3) If ABα, and rule Bε does NOT exist: FIRST(A)FIRST(B) 4) If ABα, and rule Bε DOES exist: FIRST(A)[FIRST(B)- ε] υ FIRST(α)

336
**FIRST(A)[FIRST(B)- ε] υ FIRST(α)**

FIRST Set Calculation Another example… Given the grammar: <S> ::= <A><B> <A> ::= a | ε <B> ::= b FIRST(A) = {a, ε} (2nd rule) FIRST(B) = {b} (2nd rule) FIRST(S) = [FIRST(A)- ε] υ FIRST(B) = {a, b} (4th rule) 1) FIRST(terminal){terminal} 2) If Aaα, and a is a terminal: FIRST(A){a} 3) If ABα, and rule Bε does NOT exist: FIRST(A)FIRST(B) 4) If ABα, and rule Bε DOES exist: FIRST(A)[FIRST(B)- ε] υ FIRST(α)

337
**FOLLOW Set Calculation**

Rules to calculate the FOLLOW set: FOLLOW(S){$} (where S is the starting symbol) If A αB: FOLLOW(B) FOLLOW(A) If AαBC, and rule Cε does NOT exist: FOLLOW(B)FIRST(C) If AαBC, and rule Cε DOES exist: FOLLOW(B)[FIRST(C)- ε] υ FOLLOW(A)

338
**FOLLOW Set Calculation**

Let’s apply these rules to an example. Given the grammar: <S> ::= <A><B> <A> ::= a <B> ::= b FOLLOW(S) = {$} (1st rule) FOLLOW(A) = FIRST(B) = {b} (3rd rule) FOLLOW(B) = FOLLOW (S) = {$} (2nd rule) 1) FOLLOW(S){$} 2) If A αB: FOLLOW(B) FOLLOW(A) 3) If AαBC, and rule Cε does NOT exist: FOLLOW(B)FIRST(C) 4) If AαBC, and rule Cε DOES exist: FOLLOW(B)[FIRST(C)- ε] υ FOLLOW(A)

339
**FOLLOW Set Calculation**

Another example… Given the grammar: <S> ::= <A><B> <A> ::= a <B> ::= b | ε FOLLOW(S) = {$} (1st rule) FOLLOW(A) = [FIRST(B)- ε]υFOLLOW(S) = {b, $} (4th rule) FOLLOW(B) = FOLLOW (S) = {$} (2nd rule) 1) FOLLOW(S){$} 2) If A αB: FOLLOW(B) FOLLOW(A) 3) If AαBC, and rule Cε does NOT exist: FOLLOW(B)FIRST(C) 4) If AαBC, and rule Cε DOES exist: FOLLOW(B)[FIRST(C)- ε] υ FOLLOW(A)

340
**FIRST(A)[FIRST(B)- ε] υ FIRST(α)**

FIRST and FOLLOW Grammar Let’s calculate FIRST and FOLLOW for each non- terminal in our famous grammar: Do the easy ones first: FIRST(factor)={num, id} FIRST(term’)={*, /, ε} FIRST(expr’)={+, -, ε} And then the more challenging ones: FIRST(term)=FIRST(factor)={num, id} FIRST(expr)=FIRST(term)={num, id} 1) FIRST(terminal){terminal} 2) If Aaα, and a is a terminal: FIRST(A){a} 3) If ABα, and rule Bε does NOT exist: FIRST(A)FIRST(B) 4) If ABα, and rule Bε DOES exist: FIRST(A)[FIRST(B)- ε] υ FIRST(α) FIRST “Rules”

341
**FOLLOW(B)[FIRST(C)- ε] υ FOLLOW(A)**

FIRST and FOLLOW Grammar Let’s calculate FIRST and FOLLOW for each non- terminal in our famous grammar: Start with the easy ones: FOLLOW(expr)={$} FOLLOW(expr’)=FOLLOW(expr)={$} 1) FOLLOW(S){$} 2) If A αB: FOLLOW(B) FOLLOW(A) 3) If AαBC, and rule Cε does NOT exist: FOLLOW(B)FIRST(C) 4) If AαBC, and rule Cε DOES exist: FOLLOW(B)[FIRST(C)- ε] υ FOLLOW(A) FOLLOW “Rules”

342
**FOLLOW(B)[FIRST(C)- ε] υ FOLLOW(A)**

FIRST and FOLLOW Grammar Let’s calculate FIRST and FOLLOW for each non- terminal in our famous grammar: Let’s do the harder ones: FOLLOW(term)=[FIRST(expr’)-ε]υFOLLOW(expr) = {+, -, $} FOLLOW(factor)=[FIRST(term’)-ε]υFOLLOW(term) = {*, /, +, -, $} FOLLOW(term’)= FOLLOW(term) 1) FOLLOW(S){$} 2) If A αB: FOLLOW(B) FOLLOW(A) 3) If AαBC, and rule Cε does NOT exist: FOLLOW(B)FIRST(C) 4) If AαBC, and rule Cε DOES exist: FOLLOW(B)[FIRST(C)- ε] υ FOLLOW(A) FOLLOW “Rules”

343
**FIRST and FOLLOW Summary: Using these sets, we build a parse table**

This parse table is necessary to perform LL(1) parsing FIRST(expr)= {num, id} FIRST(expr’)= {+, -, ε} FIRST(term)= {num, id} FIRST(term’)= {*, /, ε} FIRST(factor)= {num, id} FOLLOW(expr)={$} FOLLOW(expr’)={$} FOLLOW(term)= {+, -, $} FOLLOW(term’)= {+, -, $} FOLLOW(factor)= {*, /, +, -, $}

344
**Parse Table We will add two entries associated with num and id**

FIRST Sets FOLLOW Sets Grammar FIRST(expr)= {num, id} FIRST(expr’)= {+, -, ε} FIRST(term)= {num, id} FIRST(term’)= {*, /, ε} FIRST(factor)= {num, id} FOLLOW(expr)={$} FOLLOW(expr’)={$} FOLLOW(term)= {+, -, $} FOLLOW(term’)= {+, -, $} FOLLOW(factor)= {*, /, +, -, $} We will add two entries associated with num and id num id + - * / $ expr expr’ term term’ factor

345
**<term><expr’>**

Parse Table FIRST Sets FOLLOW Sets Grammar FIRST(expr)= {num, id} FIRST(expr’)= {+, -, ε} FIRST(term)= {num, id} FIRST(term’)= {*, /, ε} FIRST(factor)= {num, id} FOLLOW(expr)={$} FOLLOW(expr’)={$} FOLLOW(term)= {+, -, $} FOLLOW(term’)= {+, -, $} FOLLOW(factor)= {*, /, +, -, $} We will add two entries associated with num and id num id + - * / $ expr <expr> <term><expr’> expr’ term term’ factor

346
**<term><expr’>**

Parse Table FIRST Sets FOLLOW Sets Grammar FIRST(expr)= {num, id} FIRST(expr’)= {+, -, ε} FIRST(term)= {num, id} FIRST(term’)= {*, /, ε} FIRST(factor)= {num, id} FOLLOW(expr)={$} FOLLOW(expr’)={$} FOLLOW(term)= {+, -, $} FOLLOW(term’)= {+, -, $} FOLLOW(factor)= {*, /, +, -, $} Fill the expr’ in the same way num id + - * / $ expr <expr> <term><expr’> expr’ term term’ factor

347
**<term><expr’>**

Parse Table FIRST Sets FOLLOW Sets Grammar FIRST(expr)= {num, id} FIRST(expr’)= {+, -, ε} FIRST(term)= {num, id} FIRST(term’)= {*, /, ε} FIRST(factor)= {num, id} FOLLOW(expr)={$} FOLLOW(expr’)={$} FOLLOW(term)= {+, -, $} FOLLOW(term’)= {+, -, $} FOLLOW(factor)= {*, /, +, -, $} Fill the expr’ in the same way num id + - * / $ expr <expr> <term><expr’> expr’ <expr’> +<expr> -<expr> term term’ factor

348
**<term><expr'>**

Parse Table FIRST Sets FOLLOW Sets Grammar FIRST(expr)= {num, id} FIRST(expr’)= {+, -, ε} FIRST(term)= {num, id} FIRST(term’)= {*, /, ε} FIRST(factor)= {num, id} FOLLOW(expr)={$} FOLLOW(expr’)={$} FOLLOW(term)= {+, -, $} FOLLOW(term’)= {+, -, $} FOLLOW(factor)= {*, /, +, -, $} What about the epsilon? Use the FOLLOW set to add the epsilon rule… num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> term term’ factor

349
**<term><expr'>**

Parse Table FIRST Sets FOLLOW Sets Grammar FIRST(expr)= {num, id} FIRST(expr’)= {+, -, ε} FIRST(term)= {num, id} FIRST(term’)= {*, /, ε} FIRST(factor)= {num, id} FOLLOW(expr)={$} FOLLOW(expr’)={$} FOLLOW(term)= {+, -, $} FOLLOW(term’)= {+, -, $} FOLLOW(factor)= {*, /, +, -, $} What about the epsilon? Use the FOLLOW set to add the epsilon rule… num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term term’ factor

350
**<term><expr'>**

Parse Table FIRST Sets FOLLOW Sets Grammar FIRST(expr)= {num, id} FIRST(expr’)= {+, -, ε} FIRST(term)= {num, id} FIRST(term’)= {*, /, ε} FIRST(factor)= {num, id} FOLLOW(expr)={$} FOLLOW(expr’)={$} FOLLOW(term)= {+, -, $} FOLLOW(term’)= {+, -, $} FOLLOW(factor)= {*, /, +, -, $} No, epsilon, just use the FIRST set num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term term’ factor

351
**Parse Table No, epsilon, just use the FIRST set FIRST(expr)= {num, id}**

FIRST Sets FOLLOW Sets Grammar FIRST(expr)= {num, id} FIRST(expr’)= {+, -, ε} FIRST(term)= {num, id} FIRST(term’)= {*, /, ε} FIRST(factor)= {num, id} FOLLOW(expr)={$} FOLLOW(expr’)={$} FOLLOW(term)= {+, -, $} FOLLOW(term’)= {+, -, $} FOLLOW(factor)= {*, /, +, -, $} No, epsilon, just use the FIRST set num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ factor

352
**Parse Table This one has an epsilon, use the FIRST and FOLLOW sets**

FIRST Sets FOLLOW Sets Grammar FIRST(expr)= {num, id} FIRST(expr’)= {+, -, ε} FIRST(term)= {num, id} FIRST(term’)= {*, /, ε} FIRST(factor)= {num, id} FOLLOW(expr)={$} FOLLOW(expr’)={$} FOLLOW(term)= {+, -, $} FOLLOW(term’)= {+, -, $} FOLLOW(factor)= {*, /, +, -, $} This one has an epsilon, use the FIRST and FOLLOW sets num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ factor

353
**Parse Table This one has an epsilon, use the FIRST and FOLLOW sets**

FIRST Sets FOLLOW Sets Grammar FIRST(expr)= {num, id} FIRST(expr’)= {+, -, ε} FIRST(term)= {num, id} FIRST(term’)= {*, /, ε} FIRST(factor)= {num, id} FOLLOW(expr)={$} FOLLOW(expr’)={$} FOLLOW(term)= {+, -, $} FOLLOW(term’)= {+, -, $} FOLLOW(factor)= {*, /, +, -, $} This one has an epsilon, use the FIRST and FOLLOW sets num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor

354
**Parse Table Fill the row for factor… FIRST(expr)= {num, id}**

FIRST Sets FOLLOW Sets Grammar FIRST(expr)= {num, id} FIRST(expr’)= {+, -, ε} FIRST(term)= {num, id} FIRST(term’)= {*, /, ε} FIRST(factor)= {num, id} FOLLOW(expr)={$} FOLLOW(expr’)={$} FOLLOW(term)= {+, -, $} FOLLOW(term’)= {+, -, $} FOLLOW(factor)= {*, /, +, -, $} Fill the row for factor… num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor

355
**Parse Table Fill the row for factor… FIRST(expr)= {num, id}**

FIRST Sets FOLLOW Sets Grammar FIRST(expr)= {num, id} FIRST(expr’)= {+, -, ε} FIRST(term)= {num, id} FIRST(term’)= {*, /, ε} FIRST(factor)= {num, id} FOLLOW(expr)={$} FOLLOW(expr’)={$} FOLLOW(term)= {+, -, $} FOLLOW(term’)= {+, -, $} FOLLOW(factor)= {*, /, +, -, $} Fill the row for factor… num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id

356
**Parse Table Add dashes to the remaining cells to indicate: no entry**

FIRST Sets FOLLOW Sets Grammar FIRST(expr)= {num, id} FIRST(expr’)= {+, -, ε} FIRST(term)= {num, id} FIRST(term’)= {*, /, ε} FIRST(factor)= {num, id} FOLLOW(expr)={$} FOLLOW(expr’)={$} FOLLOW(term)= {+, -, $} FOLLOW(term’)= {+, -, $} FOLLOW(factor)= {*, /, +, -, $} Add dashes to the remaining cells to indicate: no entry num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id

357
**Parse Table FIRST(expr)= {num, id} FIRST(expr’)= {+, -, ε}**

FIRST Sets FOLLOW Sets Grammar FIRST(expr)= {num, id} FIRST(expr’)= {+, -, ε} FIRST(term)= {num, id} FIRST(term’)= {*, /, ε} FIRST(factor)= {num, id} FOLLOW(expr)={$} FOLLOW(expr’)={$} FOLLOW(term)= {+, -, $} FOLLOW(term’)= {+, -, $} FOLLOW(factor)= {*, /, +, -, $} num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id

358
Parsing Using LL(1) In order to implement an LL(1) parser, we need to use the following data structures: Parsing table (can be implemented with a 2D array or something fancier) Stack (that will contain the derivations) List (that will contain the token input stream)

359
**Parsing Using LL(1) Example: id - num * id $ Token stream list**

Parse Table num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id Derivation Stack $

360
**Parsing Using LL(1) Example: id - num * id $**

Start by pushing the starting symbol (goal) into the stack num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id $

361
**Parsing Using LL(1) Example: id - num * id $**

Start by pushing the starting symbol (goal) into the stack num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id expr $

362
**Parsing Using LL(1) Example: id - num * id $ expr $**

On the head of the input stream, we have id On the top of the stack, we have expr Using the parsing table, we retrieve the rule: <expr><term><expr’> num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id expr $

363
**Parsing Using LL(1) Example: id - num * id $ expr $**

POP expr and PUSH term and expr’ num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id expr $

364
**Parsing Using LL(1) Example: id - num * id $ term expr’ $**

On the head of the input stream, we have id On the top of the stack, we have term Using the parsing table, we retrieve the rule: <term><factor><term’> num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id term expr’ $

365
**Parsing Using LL(1) Example: id - num * id $ term expr’ $**

POP term and PUSH factor and term’ num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id term expr’ $

366
**Parsing Using LL(1) Example: id - num * id $ factor term’ expr’ $**

On the head of the input stream, we have id On the top of the stack, we have factor Using the parsing table, we retrieve the rule: <factor>id num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id factor term’ expr’ $

367
**Parsing Using LL(1) Example: id - num * id $ id term’ expr’ $**

Whenever we have a terminal on top of the stack, we check if it matches the head of the list If it does not syntax does not follow grammar If it does, REMOVE head of the list and POP the stack num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id id term’ expr’ $

368
**Parsing Using LL(1) Example: - num * id $ term’ expr’ $**

Whenever we have a terminal on top of the stack, we check if it matches the head of the list If it does not syntax does not follow grammar If it does, REMOVE head of the list and POP the stack num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id term’ expr’ $

369
**Parsing Using LL(1) Example: - num * id $ term’ expr’ $**

On the head of the input stream, we have - On the top of the stack, we have term’ Using the parsing table, we retrieve the rule: <term’>ε Therefore, we should simply POP num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id term’ expr’ $

370
**Parsing Using LL(1) Example: - num * id $ expr’ $**

And continue the same way… num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id expr’ $

371
**Parsing Using LL(1) Example: - num * id $ - expr $**

And continue the same way… num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id - expr $

372
**Parsing Using LL(1) Example: num * id $ expr $**

And continue the same way… num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id expr $

373
**Parsing Using LL(1) Example: num * id $ term expr’ $**

And continue the same way… num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id term expr’ $

374
**Parsing Using LL(1) Example: num * id $ factor term’ expr’ $**

And continue the same way… num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id factor term’ expr’ $

375
**Parsing Using LL(1) Example: num * id $ num term’ expr’ $**

And continue the same way… num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id num term’ expr’ $

376
**Parsing Using LL(1) Example: * id $ term’ expr’ $**

And continue the same way… num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id term’ expr’ $

377
**Parsing Using LL(1) Example: * id $ * term expr’ $**

And continue the same way… num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id * term expr’ $

378
**Parsing Using LL(1) Example: id $ term expr’ $**

And continue the same way… num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id term expr’ $

379
**Parsing Using LL(1) Example: id $ factor term’ expr’ $**

And continue the same way… num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id factor term’ expr’ $

380
**Parsing Using LL(1) Example: id $ id term’ expr’ $**

And continue the same way… num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id id term’ expr’ $

381
**Parsing Using LL(1) Example: $ term’ expr’ $**

And continue the same way… num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id term’ expr’ $

382
**Parsing Using LL(1) Example: $ expr’ $ And continue the same way… num**

id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id expr’ $

383
**We have verified that the input string is a sentence of the grammar!!**

Parsing Using LL(1) Example: $ We have verified that the input string is a sentence of the grammar!! num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id $

384
Section 12 More on LL Parsing

385
Topics Non LL(1) Grammar Error Recovery LL(K) Parsers

386
**A Non LL(1) Grammar Consider the grammar:**

<stmt> ::= if <expr> then <stmt> | if <expr> then <stmt> else <stmt> Needs left factoring, which gives: <stmt> ::= if <expr> then <stmt><stmt’> <stmt’> ::= else <stmt> | ε Let’s get the FIRST and FOLLOW sets FIRST(stmt) = {if} FIRST(stmt’)={else, ε} FOLLOW(stmt) = {$, else} FOLLOW(stmt’)={$, else} Note: This is a partial grammar (used to demonstrate a concept), therefore we did not specify the production rules associated with expr. Consequently, its FIRST and FOLLOW sets will not be calculated.

387
A Non LL(1) Grammar FIRST(stmt) = {if} FIRST(stmt’)={else, ε} … FOLLOW(stmt) = {$, else} FOLLOW(stmt’)={$, else} … <stmt> ::= if <expr> then <stmt><stmt’> <stmt’> ::= else <stmt> | ε if then else $ stmt stmt’

388
**if <expr> then <stmt><stmt’>**

A Non LL(1) Grammar FIRST(stmt) = {if} FIRST(stmt’)={else, ε} … FOLLOW(stmt) = {$, else} FOLLOW(stmt’)={$, else} … <stmt> ::= if <expr> then <stmt><stmt’> <stmt’> ::= else <stmt> | ε if then else $ stmt <stmt> if <expr> then <stmt><stmt’> - stmt’

389
**if <expr> then <stmt><stmt’>**

A Non LL(1) Grammar FIRST(stmt) = {if} FIRST(stmt’)={else, ε} … FOLLOW(stmt) = {$, else} FOLLOW(stmt’)={$, else} … <stmt> ::= if <expr> then <stmt><stmt’> <stmt’> ::= else <stmt> | ε if then else $ stmt <stmt> if <expr> then <stmt><stmt’> - stmt’ <stmt’> else <stmt>

390
**if <expr> then <stmt><stmt’>**

A Non LL(1) Grammar FIRST(stmt) = {if} FIRST(stmt’)={else, ε} … FOLLOW(stmt) = {$, else} FOLLOW(stmt’)={$, else} … <stmt> ::= if <expr> then <stmt><stmt’> <stmt’> ::= else <stmt> | ε if then else $ stmt <stmt> if <expr> then <stmt><stmt’> - stmt’ <stmt’> else <stmt> <stmt’> ε

391
**if <expr> then <stmt><stmt’>**

A Non LL(1) Grammar FIRST(stmt) = {if} FIRST(stmt’)={else, ε} … FOLLOW(stmt) = {$, else} FOLLOW(stmt’)={$, else} … <stmt> ::= if <expr> then <stmt><stmt’> <stmt’> ::= else <stmt> | ε if then else $ stmt <stmt> if <expr> then <stmt><stmt’> - stmt’ <stmt’> else <stmt>, <stmt’> ε

392
**if <expr> then <stmt><stmt’>**

A Non LL(1) Grammar The problem arises because for an input token else and stack top of stmt, we do not know which production to choose: <stmt’>else <stmt> <stmt’>ε Therefore, this is not an LL(1) grammar if then else $ stmt <stmt> if <expr> then <stmt><stmt’> - stmt’ <stmt’> else <stmt>, <stmt’> ε

393
**LL(1) Error Recovery What happens when the parser discovers an error?**

Approach 1: stop all parsing activity and return an error message Approach 2: try to continue parsing (if possible) and see if there are more errors along the way Which approach does your compiler take? At Nothing!

394
**LL(1) Error Recovery An error is detected when:**

The terminal on top of the stack does not match the next input token The parsing table cell from which we are supposed to pull the next production is empty What does the parser do? It enters the panic-mode error recovery Based on the idea of skipping symbols on the input until a token in a selected set of synchronizing tokens appears

395
LL(1) Error Recovery Let S be a set of tokens called a synchronization set. Let s ∊ S s is called a synchronization token Million dollar question: how to construct the synchronization set? Many heuristics have been proposed We will cover a simple method Place all symbols in FOLLOW(A) into the synchronizing set for nonterminal A If we skip tokens until an element of FOLLOW(A) is seen and we pop A from the stack, it’s likely that parsing can continue.

396
LL(1) Error Recovery The panic-mode error recovery can be implemented using the synchronization set(s) as follows: If there is a nonterminal at the top of the stack, discard input tokens until you find a synch token, then pop the non-terminal If there is a terminal at the top of the stack, we could try popping it to see whether we can continue Assume that the input string is actually missing that terminal

397
**LL(1) Error Recovery Example**

FIRST Sets FOLLOW Sets Grammar FIRST(expr)= {num, id} FIRST(expr’)= {+, -, ε} FIRST(term)= {num, id} FIRST(term’)= {*, /, ε} FIRST(factor)= {num, id} FOLLOW(expr)={$} FOLLOW(expr’)={$} FOLLOW(term)= {+, -, $} FOLLOW(term’)= {+, -, $} FOLLOW(factor)= {*, /, +, -, $} num id + - * / $ expr <expr> <term><expr'> expr’ <expr’> +<expr> -<expr> ε term <term> <factor><term’> term’ <term’> *<term> /<term> factor factor num factor id 397 SEG Hussein Al Osman - Winter 2014

398
**LL(1) Error Recovery Example**

FIRST Sets FOLLOW Sets Grammar FIRST(expr)= {num, id} FIRST(expr’)= {+, -, ε} FIRST(term)= {num, id} FIRST(term’)= {*, /, ε} FIRST(factor)= {num, id} FOLLOW(expr)={$} FOLLOW(expr’)={$} FOLLOW(term)= {+, -, $} FOLLOW(term’)= {+, -, $} FOLLOW(factor)= {*, /, +, -, $} num id + - * / $ expr <expr> <term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id 398 SEG Hussein Al Osman - Winter 2014

399
**Parsing Using LL(1) Example: id * / / + num + id $ String of errors**

- * / $ expr <expr> <term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id expr $

400
**Parsing Using LL(1) Example: id * / / + num + id $ term expr’ $ num id**

- * / $ expr <expr> <term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id term expr’ $

401
**Parsing Using LL(1) Example: id * / / + num + id $ factor term' expr’**

- * / $ expr <expr> <term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id factor term' expr’ $

402
**Parsing Using LL(1) Example: id * / / + num + id $ id term' expr’ $**

- * / $ expr <expr> <term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id id term' expr’ $

403
**Parsing Using LL(1) Example: * / / + num + id $ term' expr’ $ num id +**

- * / $ expr <expr> <term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id term' expr’ $

404
**Parsing Using LL(1) Example: * / / + num + id $ * term expr’ $ num id**

- * / $ expr <expr> <term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id * term expr’ $

405
**Parsing Using LL(1) Example: / / + num + id $**

Error: the cell corresponding to row term and column / is empty! Start discarding tokens, until you find a synch token num id + - * / $ expr <expr> <term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id term expr’ $

406
**Parsing Using LL(1) Example: / + num + id $**

Error: the cell corresponding to row term and column / is empty! Start discarding tokens, until you find a synch token num id + - * / $ expr <expr> <term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id term expr’ $

407
**Parsing Using LL(1) Example: + num + id $**

Error: the cell corresponding to row term and column / is empty! Start discarding tokens, until you find a synch token num id + - * / $ expr <expr> <term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id term expr’ $

408
**Parsing Using LL(1) Example: + num + id $ We have found a synch token!**

Pop term from the stack and attempt to continue… num id + - * / $ expr <expr> <term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id term expr’ $

409
**Parsing Using LL(1) Example: + num + id $ expr’ $ num id + - * / $**

<term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id expr’ $

410
**Parsing Using LL(1) Example: + num + id $ + expr $ num id + - * / $**

<term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id + expr $

411
**Parsing Using LL(1) Example: num + id $ expr $ num id + - * / $ expr**

<term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id expr $

412
**Parsing Using LL(1) Example: num + id $ term expr' $ num id + - * / $**

<factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id term expr' $

413
**Parsing Using LL(1) Example: num + id $ factor term’ expr' $ num id +**

- * / $ expr <expr> <term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id factor term’ expr' $

414
**Parsing Using LL(1) Example: num + id $ num term’ expr' $ num id + - ***

/ $ expr <expr> <term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id num term’ expr' $

415
**Parsing Using LL(1) Example: + id $ term’ expr' $ num id + - * / $**

<factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id term’ expr' $

416
**Parsing Using LL(1) Example: + id $ expr' $ num id + - * / $ expr**

<term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id expr' $

417
**Parsing Using LL(1) Example: + id $ + expr $ num id + - * / $ expr**

<term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id + expr $

418
**Parsing Using LL(1) Example: id $ expr $ num id + - * / $ expr**

<term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id expr $

419
**Parsing Using LL(1) Example: id $ term expr' $ num id + - * / $ expr**

<factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id term expr' $

420
**Parsing Using LL(1) Example: id $ factor term' expr' $ num id + - * /**

*<term> (s) /<term> (s) factor factor num factor id factor term' expr' $

421
**Parsing Using LL(1) Example: id $ id term' expr' $ num id + - * / $**

<factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id id term' expr' $

422
**Parsing Using LL(1) Example: $ term' expr' $ num id + - * / $ expr**

<factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id term' expr' $

423
**Parsing Using LL(1) Example: $ expr' $ num id + - * / $ expr**

<term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id expr' $

424
**We did our best to continue parsing…**

Parsing Using LL(1) Example: $ We did our best to continue parsing… num id + - * / $ expr <expr> <term><expr'> (s) expr’ <expr’> +<expr> -<expr> ε (s) term <term> <factor><term’> term’ <term’> *<term> (s) /<term> (s) factor factor num factor id $

425
**LL(k) Parsers We have already studies LL(1) parser**

With 1 token look-ahead We will touch briefly on LL(k) parsers With “k” tokens look-ahead This is useful since not all grammars are LL(1) compatible

426
**LL(k) Parsers Consider the following grammar: First and Follow sets:**

<Z> ::= <X><Y><Z>| a | ab <Y> ::= c | ε <X> ::= a | b<Y>c First and Follow sets: FIRST(Z)={a,b} FOLLOW(Z)={$} FIRST(Y)={c, ε} FOLLOW(Y)={a,b,c} FIRST(X)={a,b} FOLLOW(X)={a,b,c}

427
**LL(k) Parsers Grammar FIRST FOLLOW a b c $ X Y Z**

<Z> ::= <X><Y><Z>| a | ab <Y> ::= c | ε <X> ::= a | b<Y>c FIRST(Z)={a,b} FIRST(Y)={c, ε} FIRST(X)={a,b} FOLLOW(Z)={$} FOLLOW(Y)={a,b,c} FOLLOW(X)={a,b,c} a b c $ X Y Z

428
**LL(k) Parsers Grammar FIRST FOLLOW a b c $ X Xa XbYc - Y Z**

<Z> ::= <X><Y><Z>| a | ab <Y> ::= c | ε <X> ::= a | b<Y>c FIRST(Z)={a,b} FIRST(Y)={c, ε} FIRST(X)={a,b} FOLLOW(Z)={$} FOLLOW(Y)={a,b,c} FOLLOW(X)={a,b,c} a b c $ X Xa XbYc - Y Z

429
**LL(k) Parsers Grammar FIRST FOLLOW a b c $ X Xa XbYc - Y Yε Yc, Z**

<Z> ::= <X><Y><Z>| a | ab <Y> ::= c | ε <X> ::= a | b<Y>c FIRST(Z)={a,b} FIRST(Y)={c, ε} FIRST(X)={a,b} FOLLOW(Z)={$} FOLLOW(Y)={a,b,c} FOLLOW(X)={a,b,c} a b c $ X Xa XbYc - Y Yε Yc, Z

430
**LL(k) Parsers Grammar FIRST FOLLOW a b c $ X Xa XbYc - Y Yε Yc, Z**

<Z> ::= <X><Y><Z>| a | ab <Y> ::= c | ε <X> ::= a | b<Y>c FIRST(Z)={a,b} FIRST(Y)={c, ε} FIRST(X)={a,b} FOLLOW(Z)={$} FOLLOW(Y)={a,b,c} FOLLOW(X)={a,b,c} a b c $ X Xa XbYc - Y Yε Yc, Z Za Zab ZXYZ Not an LL(1) Grammar

431
**LL(k) Parsers We have shown that the above grammar is not LL(1)**

<Z> ::= <X><Y><Z>| a | ab <Y> ::= c | ε <X> ::= a | b<Y>c Grammar We have shown that the above grammar is not LL(1) Maybe it is an LL(2) grammar Re-create the sets FIRST(α) while considering a max of TWO terminals appearing first in a string derived from α Re-create the sets FOLLOW (α) while considering a max of TWO terminals appearing after α in a sentential form Make sure that a single production exists in every table cell

432
Section 13 LR Parsing

433
Topics Bottom Up parsing Right Most Derivation Shift and Reduce Operations LR Parsers

434
**Top Down Parsing So far we have studied Top Down Parsing extensively**

Nonetheless, we have not seen Top Down Parsing with right most derivation We have worked exclusively so far with left most derivation We always eliminate non-terminals in the parsing tree from left to right

435
**Right Most Derivation Derivation**

Grammar <expr> <term><expr’> <term>+<expr> <term>+<term><expr’> <term>+<term> <term>+<factor><term’> <term>+<factor> <term>+id <factor><term’>+id <factor>+id id+id Input String: id+id

436
Bottom Up Parsing A bottom up parser builds a parsing tree starting from the input string Input string will constitute the leafs of the tree A parent node A can be added to the tree if: There exists several “parentless” neighboring nodes (n1, n2, … nn) for which there exists a production: <A> ::= n1n2 … nn A is added as the parent of nodes n1, n2, … nn This action is called REDUCTION

437
**Reached the starting symbol!**

Bottom Up Parsing Example: Given the grammar: <A> ::= a<B> <B> ::= b | cd<B> And the input string: acdcdb We can build the parsing tree as follows: Reached the starting symbol! A B B B a c d c d b

438
**LR Parser LR parser is a bottom up parser**

It provides a mechanism to build a parse tree incrementally, without backtracking Advantages of LR parsing (over LL parsing): No need to eliminate left recursion No need for left factoring The previous example of the bottom up parser lacks this predictive quality See example at the next slide…

439
**non Predictive Bottom Up Parser**

Example: Given the grammar: <A> ::= a<B> | acd <B> ::= b | cd<B> And the same input string: acdcdb We can build the parsing tree as follows: Reached the starting symbol too early! We did not process the rest of the string… A a c d c d b

440
Back to LR Parsers LR parsers rely on two main actions they perform during parsing: Shift: advances the input string by one symbol Reduce: we have discussed this action earlier (taking a group of symbols and reducing them to a single non-terminal) If the input string has no errors (is a sentence of the grammar): The parser continues to perform these actions until all of the input has been consumed At which point, the parse tree is complete, with the starting symbol as its root

441
**LR Parsers LR parsers MUST know when to shift and when to reduce…**

This quality makes them predictive Prevents them from backtracking (avoids guessing) LR parsers often look ahead (rightwards) at the next scanned symbol, before deciding what to do with previously scanned ones

442
Shift and Reduce LR Parsers split the sentential form into two parts: Analysed part: sequence of terminals and non-terminals Un-analyzed part: sequence of terminals For example, for the following sentential form: a A b c d Analyzed part Un-Analyzed part marker

443
**Shift and Reduce a A b c d a A b c d a Z d**

Therefore, we define the operation: Shift: as moving the marker to the right a A b c d Reduce: as replacing a string in the right-most portion of the analyzed part by its equivalent non-terminal Suppose I have a production: <Z> ::= <A>bc a A b c d a Z d

444
Using Shift And Reduce Consider the following grammar: <E> ::= <T> + <E> | <T> <T> ::= id*<T> | id | ( <E> ) Using Shift and Reduce operations, parse the following input string: id*id+id

445
**Using Shift And Reduce Sentential Form Action id * id + id Shift**

Reduce using Tid id * T + id Reduce using Tid*T T + id T + T Reduce using ET T + E Reduce using ET+E E Grammar <E> ::= <T> + <E> | <T> <T> ::= id*<T> | id | ( <E> )

446
**Using Shift And Reduce Incorrectly**

Sentential Form Action id * id + id Shift Reduce using Tid T * id + id T * T + id Reduce TE T * E + id T * E + T We are stuck! Grammar <E> ::= <T> + <E> | <T> <T> ::= id*<T> | id | ( <E> ) One bad operation and it’s all over…

447
**LR Parser We now know how to shift and reduce!**

But we do not know when to shift and when to reduce Once we know that, we achieve our purpose of never backtracking

448
Handle We reduce if the rightmost portion of the analysed part is a valid handle Otherwise, we shift Properties of the handle: Should match the right hand side of a production Its reduction should allow us to eventually reach the starting symbol Reducing the handle must constitute a step in the reverse direction of a right most top down derivation

449
Handle Derivation Grammar <E> <T>+<E> <T>+<T> <T>+id id*<T>+id id*id+id <E> ::= <T> + <E> | <T> <T> ::= id*<T> | id | ( <E> ) Input String: id*id+id

450
**Shift And Reduce with Handle**

Sentential Form Action id * id + id Shift Reduce using Tid id * T + id Reduce using Tid*T T + id T + T Reduce using ET T + E Reduce using ET+E E Grammar <E> ::= <T> + <E> | <T> <T> ::= id*<T> | id | ( <E> ) Derivation: <E> <T>+<E> <T>+<T> <T>+id id*<T>+id id*id+id

451
**Introduction to Concurrency**

Section 14 Introduction to Concurrency

452
Topics Concepts of concurrency Subprogram-level concurrency Semaphores Deadlocks

453
**Concept of Concurrency**

Concurrency can be achieved at different levels: Instruction level Statement level Unit level Program level Concurrent execution of program units can be performed: Physically on separate processors, or Logically in some time-sliced fashion on a single processor computer system

454
Why Study Concurrency? Computing systems solve real world problems, where things happen at the same time: Railway Networks (lots of trains running, but that have to synchronize on shared sections of track) Operating System, with lots of processes running concurrently Web servers Multiple processor or multi-core computers are now being widely used This creates the need for software to make effective use of that hardware capability

455
**Subprogram-Level Concurrency**

A task is a unit of program that can be executed concurrently with other units of the same program Each task in a program can provide one thread of control A task can communicate with other tasks through: Shared nonlocal variables Message passing Parameters

456
Synchronization A mechanism to control the order in which tasks execute Cooperation synchronization is required between task A and task B when: Task A must wait for task B to complete some specific activity before task A can continue execution Recall the producer-consumer petri net problem Competition synchronization is required between two tasks when: Both require the use of some resource that cannot be simultaneously used

457
**The Need for Competition Synchronization**

Value of Total = 3 4 6 Task A Fetch Total Add 1 Store Total Task B Fetch Total Multiply by 2 Store Total Time

458
**Critical Section A segment of code, in which the thread may be:**

Changing common variables, Updating a table, Writing to a file, Or updating any shared resource The execution of critical sections by the threads is mutually exclusive in time

459
Task (Thread) States New: it has been created, but has not yet begun its execution Runnable or ready: it is ready to run, but is not currently running Running: it is currently executing, it has a processor and its code is being executed Blocked: it has been running, but its execution was interrupted by one of several different events Dead: no longer active in any sense

460
Semaphores Semaphore is a technique used to control access to common resource for multiple tasks It is a data structure consisting of an integer and a queue that stores task descriptors A task that requires access to a critical section needs to “acquire” the semaphore Classically: a system of sending messages by holding the arms of two flags in certain positions according to an alphabetic code

461
**Semaphores Two operations are always associated with Semaphores**

Operation “P” is used to get the semaphore, and “V” to release it P (proberen, meaning to test and decrement the integer) V (verhogen, meaning to increment) operation Alternatively, these operations are called: wait and release

462
Semaphores Operating systems often distinguish between counting and binary semaphores The value of a counting semaphore can range over an unrestricted domain. The value of a binary semaphore can range only between 0 and 1

463
Semaphores The general strategy for using a binary semaphore to control access to a critical section is as follows: Semaphore aSemaphore; P(aSemaphore); Critical section(); V(aSemaphore);

464
**Cooperation Synchronization**

wait(aSemaphore); if aSemaphore’s counter > 0 then Decrement aSemaphore’s counter else Set the task’s state to blocked Put the caller in aSemaphore’s queue end

465
**Cooperation Synchronization**

release(aSemaphore); if aSemaphore’s queue is empty then increment aSmaphore’s counter else set the state of the task at the queue head to ready Perform a dequeue operation end

466
Producer and Consumer

467
**Adding Competition Synchronization**

468
**Competition Synchronization (II)**

469
Deadlocks A law passed by the Kansas legislature early in 20th century: “…… When two trains approach each other at a crossing, both shall come to a full stop and neither shall start up again until the other has gone. ……”

470
Deadlock Classic case of traffic deadlock. This is a gridlock where not vehicle can move forward to clear the traffic jam

471
**Conditions for Deadlock**

Mutual exclusion: the act of allowing only one process to have access to a dedicated resource Hold-and-wait: there must be a process holding at least one resource and waiting to acquire additional ones that are currently being held by other processes No preemption: the lack of temporary reallocation of resources, can be released only voluntarily Circular waiting: each process involved in the impasse is waiting for another to voluntarily release the resource

472
**Deadlock Example BinarySemaphore s1, s2; Task A: wait(s1)**

// access resource 1 wait (s2) // access resource 2 release(s2) release(s1) end task Task B: wait(s2) // access resource 2 wait(s1) // access resource 1 release(s1) release(s2) end task

473
**Strategy for Handling Deadlocks**

Prevention: eliminate one of the necessary conditions Avoidance: avoid if the system knows ahead of time the sequence of resource quests associated with each active processes Detection: detect by building directed resource graphs and looking for circles Recovery: once detected, it must be untangled and the system returned to normal as quickly as possible Process termination Resource preemption

474
Section 15 More on Concurrency

475
Topics Monitors Monitor Examples Asynchronous Message Passing Synchronous Message Passing Intro to Java Threads

476
Monitor A monitor is a set of multiple routines which are protected by a mutual exclusion lock None of the routines in the monitor can be executed by a thread until that thread acquires the lock Any other threads must wait for the thread that is currently executing to give up control of the lock

477
Monitor A thread can actually suspend itself inside a monitor and then wait for an event to occur If this happens, then another thread is given the opportunity to enter the monitor Usually, a thread suspends itself while waiting for a condition During the wait, the thread temporarily gives up its exclusive access It must reacquire it after the condition has been met.

478
Monitor vs Semaphore A semaphore is a simpler construct than a monitor because it’s just a lock that protects a shared resource Not a set of routes like a monitor An task must acquire (or wait for) a semaphore before accessing a shared resource A task must simply call a routine (or procedure) in the monitor in order access a shared resource When done, you do not have to release anything Remember you have to release semaphores (if you forget deadlock)

479
**Competition Synchronization**

One of the most important features of monitors is that shared data is resident in the monitor All synchronization code is centralized in one location This is in contrast to being in the competing tasks The monitor guarantees synchronization by allowing access to only one task at time Remember that using counting semaphores, we are able to allow multiple tasks access, not necessarily only one Calls to monitor procedures are implicitly queued if the monitor is busy at the time of the call

480
**Cooperation Synchronization**

Although mutually exclusive access to shared data is intrinsic with a monitor: Cooperation between processes is still the task of the programmer Programmer must guarantee that a shared buffer does not experience underflow or overflow

481
**Example of Using Monitor**

Task A procedure_1 Call procedure_1 Queue Task B procedure_2 Task C procedure_3 Task D procedure_4 Monitor Owner: none

482
**Example of Using Monitor**

Task A procedure_1 Call procedure_1 Queue Task B procedure_2 Task C procedure_3 Task D procedure_4 Monitor Owner: none

483
**Example of Using Monitor**

Task A procedure_1 Queue Task B procedure_2 Task C procedure_3 Task D procedure_4 Monitor Owner: Task A

484
**Example of Using Monitor**

Task A procedure_1 Queue Task B procedure_2 Task C procedure_3 Call procedure_2 Task D procedure_4 Monitor Owner: Task A

485
**Example of Using Monitor**

Task A procedure_1 Queue Task B procedure_2 Task C Task C procedure_3 Task D procedure_4 Monitor Owner: Task A

486
**Example of Using Monitor**

Task A procedure_1 Queue Task B procedure_2 Call procedure_4 Task C Task C procedure_3 Task D procedure_4 Monitor Owner: Task A

487
**Example of Using Monitor**

Task A procedure_1 Queue Task B procedure_2 Task B Task C Task C procedure_3 Task D procedure_4 Monitor Owner: Task A

488
**Example of Using Monitor**

Task A return procedure_1 Queue Task B procedure_2 Task B Task C Task C procedure_3 Task D procedure_4 Monitor Owner: Task A

489
**Example of Using Monitor**

Task A procedure_1 Queue Task B procedure_2 Task B Task C Task C procedure_3 Task D procedure_4 Monitor Owner: none

490
**Example of Using Monitor**

Task A procedure_1 Queue Task B procedure_2 Task B Task C procedure_3 Task D procedure_4 Monitor Owner: Task C

491
**Example of Using Monitor**

Task A procedure_1 Queue Task B procedure_2 return Task B Task C procedure_3 Task D procedure_4 Monitor Owner: Task C

492
**Example of Using Monitor**

Task A procedure_1 Queue Task B procedure_2 Task B Task C procedure_3 Task D procedure_4 Monitor Owner: none

493
**Example of Using Monitor**

Task A procedure_1 Queue Task B procedure_2 Task C procedure_3 Task D procedure_4 Monitor Owner: Task B

494
**Example: A Shared Buffer**

MONITOR: BufferMonitor const bufferSize = 100 buffer = array [0.. bufferSize-1] next_in = 0, next_out = 0, filled = 0 procedure void deposit (item ) begin while filled == bufferSize then wait() // blocks thread in the monitor end buffer[next_in] = item next_in = (next_in + 1) mod bufferSize filled = filled + 1 signal() // free a task that has been waiting on a condition end procedure

495
**Example: A Shared Buffer**

procedure Item fetch() begin while filled == 0 then wait() // block thread in the monitor end item = buffer[next_out] next_out = (next_out + 1) mod bufferSize filled = filled – 1 signal() // free a task that has been waiting on a condition return item end procedure

496
**Example: A Shared Buffer**

Producer Consumer Task Producer begin Loop Forever // produce new item … bufferMonitor.deposit(newItem) end End Task Task Consumer begin Loop Forever newItem = bufferMonitor.fetch() // consume new item … end End Task

497
Message Passing Message passing means that one process sends a message to another process and then continues its local processing The message may take some time to get to the other process The message may be stored in the input queue of the destination process If the latter is not immediately ready to receive the message

498
Message Passing The message is received by the destination process, when: The latter arrives at a point in its local processing where it is ready to receive messages. This is known as asynchronous message passing (because sending and receiving is not at the same time) communication is a form of message passing…

499
**Asynchronous Message Passing**

Blocking send and receive operations: A receiver will be blocked if it arrives at the point where it may receive messages and no message is waiting. A sender may get blocked if there is no room in the message queue between the sender and the receiver However, in many cases, one assumes arbitrary long queues, which means that the sender will almost never be blocked

500
**Asynchronous Message Passing**

Non-blocking send and receive operations: Send and receive operations always return immediately They return a status value which could indicate that no message has arrived at the receiver The receiver may test whether a message is waiting and possibly do some other processing.

501
**Synchronous Message Passing**

One assumes that sending and receiving takes place at the same time There is often no need for an intermediate buffer This is also called rendezvous and implies closer synchronization: The combined send-and-receive operation can only occur if both parties are ready to do their part. The sending process may have to wait for the receiving process, or the receiving process may have to wait for the sending one.

502
**Rendezvous (Not as romantic as it sounds!)**

503
Java Threads

504
Multiple Threads A thread is a flow of execution, with a beginning and an end, of a task in a program With Java, multiple threads from a program can be launched concurrently Multiple threads can be executed in multiprocessor systems, and single- processor systems Multithreading can make program more responsive, interactive, as well as enhance performance

505
Thread States

506
**Creating threads by extending the thread class**

507
**Creating threads by implementing the runnable interface**

508
**Thread Groups A thread group is a set of threads**

Some programs contain quite a few threads with similar functionality We can group them together and perform operations in the entire group E.g., we can suspend or resume all of the threads in a group at the same time.

509
**Using Thread Groups Construct a thread group:**

ThreadGroup g = new ThreadGroup(“thread group”); Place a thread in a thread group: Thread t = new Thread(g, new ThreadClass(),”this thread”); Find out how many threads in a group are currently running: System.out.println(“the number of runnable threads in the group “ + g.activeCount()); Find which group a thread belongs to: theGroup = myThread.getThreadGroup();

510
**Priorities The priories of threads need not all be the same**

The default thread priority is: NORM_PRIORITY(5) The priority is an integer number between 1 and 10, where: MAX_PRIORITY(10) MIN_PRIORITY(1) You can use: setPriority(int): change the priority of this thread getPriority(): return this thread’s priority

511
Section 16 Java Concurrency

512
**Topics More on Java Threads Basics Sleep Join Interrupt**

Java Semaphores Java Intrinsic Locks Monitors Implemented with Intrinsic Locks Monitors Implemented with Lock and Condition Interfaces Atomic Variables

513
**Java Thread Basics Making a thread sleep for a number of milliseconds**

Very popular with gaming applications (2D or 3D animation) Thread.sleep(1000); Thread.sleep(1000, 1000); (accuracy depends on system) Notice that these methods are static They thrown an InterruptedException

514
Java Thread Basics If you create several threads, each one is responsible for some computations You can wait for the threads to die Before putting together the results from these threads To do that, we use the join method defined in the Thread class try {thread.join();} catch (InterruptedException e){e.printStackTrace();} Exception is thrown if another thread has interrupted the current thread

515
**Join Example public class JoinThread {**

public static void main(String[] args) { Thread thread2 = new Thread(new WaitRunnable()); Thread thread3 = new Thread(new WaitRunnable()); thread2.start(); try {thread2.join();} catch (InterruptedException e) {e.printStackTrace();} thread3.start(); try {thread3.join(1000);} catch (InterruptedException e) {e.printStackTrace();} }

516
Join Example public class WaitRunnable implements Runnable public void run() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); }

517
Interrupting Threads In Java, you have no way to force a Thread to stop If the Thread is not correctly implemented, it can continue its execution indefinitely (rogue thread!) But you can interrupt a Thread with the interrupt() method If the thread is sleeping or joining an other Thread, an InterruptedException is thrown In this case, the interrupted status of the thread is cleared

518
Interrupt Example public class InterruptThread { public static void main(String[] args) { Thread thread1 = new Thread(new WaitRunnable()); thread1.start(); try {Thread.sleep(1000);} catch (InterruptedException e){e.printStackTrace();} thread1.interrupt(); }

519
**Interrupt Example Sample Output: Current time millis : 1274017633151**

private static class WaitRunnable implements Runnable public void run() { System.out.println("Current time millis: " + System.currentTimeMillis()); try {Thread.sleep(5000);} catch (InterruptedException e) { System.out.println("The thread has been interrupted"); System.out.println(