Points covered in this PPT: Syntax Analysis - CFG, top-down and bottom-up parsers, RDP, Predictive parser, SLR,LR(1), LALR parsers, using ambiguous grammar, Error detection and recovery, automatic construction of parsers using YACC,
Introduction to Semantic analysis-Need of semantic analysis, type checking and type conversion.
This document discusses syntax analysis in compiler design. It begins by explaining that the lexer takes a string of characters as input and produces a string of tokens as output, which is then input to the parser. The parser takes the string of tokens and produces a parse tree of the program. Context-free grammars are introduced as a natural way to describe the recursive structure of programming languages. Derivations and parse trees are discussed as ways to parse strings based on a grammar. Issues like ambiguity and left recursion in grammars are covered, along with techniques like left factoring that can be used to transform grammars.
Yacc is a general tool for describing the input to computer programs. It generates a LALR parser that analyzes tokens from Lex and creates a syntax tree based on the grammar rules specified. Yacc was originally developed in the 1970s and generates C code for the syntax analyzer from a grammar similar to BNF. It has been used to build compilers for languages like C, Pascal, and APL as well as for other programs like document retrieval systems.
This document provides an overview of syntax analysis in compiler design. It discusses context free grammars, derivations, parse trees, ambiguity, and various parsing techniques. Top-down parsing approaches like recursive descent parsing and LL(1) parsing are described. Bottom-up techniques including shift-reduce parsing and operator precedence parsing are also introduced. The document provides examples and practice problems related to grammar rules, derivations, parse trees, and eliminating ambiguity.
In this PPT we covered all the points like..Introduction to compilers - Design issues, passes, phases, symbol table
Preliminaries - Memory management, Operating system support for compiler, Compiler support for garbage collection ,Lexical Analysis - Tokens, Regular Expressions, Process of Lexical analysis, Block Schematic, Automatic construction of lexical analyzer using LEX, LEX features and specification.
The document discusses the phases of compilation:
1. The front-end performs lexical, syntax and semantic analysis to generate an intermediate representation and includes error handling.
2. The back-end performs code optimization and generation to produce efficient machine-specific code from the intermediate representation.
3. Key phases include lexical and syntax analysis, semantic analysis, intermediate code generation, code optimization, and code generation.
This document discusses parsing and context-free grammars. It defines parsing as verifying that tokens generated by a lexical analyzer follow syntactic rules of a language using a parser. Context-free grammars are defined using terminals, non-terminals, productions and a start symbol. Top-down and bottom-up parsing are introduced. Techniques for grammar analysis and improvement like left factoring, eliminating left recursion, calculating first and follow sets are explained with examples.
This document provides an overview of a lecture on designing and analyzing computer algorithms. It discusses key concepts like what an algorithm and program are, common algorithm design techniques like divide-and-conquer and greedy methods, and how to analyze algorithms' time and space complexity. The goals of analyzing algorithms are to understand their behavior, improve efficiency, and determine whether problems can be solved within a reasonable time frame.
Deterministic Test Pattern Generation ( D-Algorithm of ATPG) (Testing of VLSI...Usha Mehta
The document discusses deterministic test pattern generation (ATPG) for combinational circuits. It provides an overview of ATPG algorithms and concepts like fault excitation, propagation, and justification. Hard and easy faults are defined based on the difficulty of controlling inputs and observing outputs. Testability measures like controllability and observability are introduced to analyze fault difficulty. Developing one's own ATPG tool is discussed, along with ideas for future extensions.
This presentation discusses the following Fuzzy logic concepts:
Introduction
Crisp Variables
Fuzzy Variables
Fuzzy Logic Operators
Fuzzy Control
Case Study
This slide is prepared By these following Students of Dept. of CSE JnU, Dhaka. Thanks To: Nusrat Jahan, Arifatun Nesa, Fatema Akter, Maleka Khatun, Tamanna Tabassum.
The document discusses ambiguous and unambiguous context-free grammars (CFGs). CFGs are classified as ambiguous if a string has two or more possible parse trees, and unambiguous otherwise. Several examples are provided to illustrate ambiguous grammars that have multiple derivations for strings, such as grammars generating expressions. Unambiguous grammars are also exemplified, including one for the language of strings with a's. The document concludes with references for further reading on ambiguity in grammars and automata theory.
A grammar is said to be regular, if the production is in the form -
A → αB,
A -> a,
A → ε,
for A, B ∈ N, a ∈ Σ, and ε the empty string
A regular grammar is a 4 tuple -
G = (V, Σ, P, S)
V - It is non-empty, finite set of non-terminal symbols,
Σ - finite set of terminal symbols, (Σ ∈ V),
P - a finite set of productions or rules,
S - start symbol, S ∈ (V - Σ)
It is on simple topic of compiler but first and foremost important topic of compiler. For Lexical Analyzing we coded in C language. So it is easy to understand .
This document describes a course on Theory of Computation. It provides information on the course objectives, which are to understand language hierarchies, construct automata for patterns, design context-free grammars, understand Turing machines and their capabilities, and understand undecidable and NP problems. It outlines 5 units that will be covered: automata fundamentals, regular expressions and languages, context-free grammar and languages, properties of context-free languages, and undecidability. It also provides the course outcomes and lists reference textbooks. The document then begins describing some key concepts from Unit 1, including formal proofs, additional proof forms, inductive proofs, and an introduction to finite automata.
FellowBuddy.com is an innovative platform that brings students together to share notes, exam papers, study guides, project reports and presentation for upcoming exams.
We connect Students who have an understanding of course material with Students who need help.
Benefits:-
# Students can catch up on notes they missed because of an absence.
# Underachievers can find peer developed notes that break down lecture and study material in a way that they can understand
# Students can earn better grades, save time and study effectively
Our Vision & Mission – Simplifying Students Life
Our Belief – “The great breakthrough in your life comes when you realize it, that you can learn anything you need to learn; to accomplish any goal that you have set for yourself. This means there are no limits on what you can be, have or do.”
Like Us - https://www.facebook.com/FellowBuddycom
6-Role of Parser, Construction of Parse Tree and Elimination of Ambiguity-06-...movocode
This document discusses the role of a parser in compiler design. It begins by explaining that a parser obtains tokens from a lexical analyzer and generates a syntax tree while also reporting any syntax errors. It then discusses the two main types of parsers: top-down and bottom-up. The document goes on to define context-free grammars and their components such as terminals, non-terminals, the start symbol, and productions. It also discusses the concepts of derivations, leftmost and rightmost derivations, and parsing ambiguities that can arise from grammars. Finally, it covers techniques for eliminating left recursion from grammars.
The document discusses N-gram language models, which assign probabilities to sequences of words. An N-gram is a sequence of N words, such as a bigram (two words) or trigram (three words). The N-gram model approximates the probability of a word given its history as the probability given the previous N-1 words. This is called the Markov assumption. Maximum likelihood estimation is used to estimate N-gram probabilities from word counts in a corpus.
This presentation discusses context-free grammars. It defines context-free grammars and provides an example. It also discusses parse trees, including how they are generated and different types (top-down and bottom-up). Examples are provided to demonstrate leftmost and rightmost derivations and parse trees. The document concludes that the grammar presented, with production rules of X → X+X | X*X |X| a, is ambiguous as there are two possible parse trees for the string "a+a*a".
The document outlines the 5 phases of natural language processing (NLP):
1. Morphological analysis breaks text into paragraphs, sentences, words and assigns parts of speech.
2. Syntactic analysis checks grammar and parses sentences.
3. Semantic analysis focuses on literal word and phrase meanings.
4. Discourse integration considers the effect of previous sentences on current ones.
5. Pragmatic analysis discovers intended effects by applying cooperative dialogue rules.
Machine learning models involve a bias-variance tradeoff, where increased model complexity can lead to overfitting training data (high variance) or underfitting (high bias). Bias measures how far model predictions are from the correct values on average, while variance captures differences between predictions on different training data. The ideal model has low bias and low variance, accurately fitting training data while generalizing to new examples.
This document provides an overview of a compiler design course, including prerequisites, textbook, course outline, and introductions to key compiler concepts. The course outline covers topics such as lexical analysis, syntax analysis, parsing techniques, semantic analysis, intermediate code generation, code optimization, and code generation. Compiler design involves translating a program from a source language to a target language. Key phases of compilation include lexical analysis, syntax analysis, semantic analysis, intermediate code generation, code optimization, and code generation. Parsing techniques can be top-down or bottom-up.
This seminar presentation provides an overview of YACC (Yet Another Compiler Compiler). It discusses what compilers do, the structure of compilers including scanners, parsers, semantic routines, code generators and optimizers. It then reviews parsers and how YACC works by taking a grammar specification and generating C code for a parser. YACC declarations and commands are also summarized.
Random Forest Algorithm widespread popularity stems from its user-friendly nature and adaptability, enabling it to tackle both classification and regression problems effectively. The algorithm’s strength lies in its ability to handle complex datasets and mitigate overfitting, making it a valuable tool for various predictive tasks in machine learning.
One of the most important features of the Random Forest Algorithm is that it can handle the data set containing continuous variables, as in the case of regression, and categorical variables, as in the case of classification. It performs better for classification and regression tasks. In this tutorial, we will understand the working of random forest and implement random forest on a classification task.
The document discusses syntax analysis and parsing. It defines a syntax analyzer as creating the syntactic structure of a source program in the form of a parse tree. A syntax analyzer, also called a parser, checks if a program satisfies the rules of a context-free grammar and produces the parse tree if it does, or error messages otherwise. It describes top-down and bottom-up parsing methods and how parsers use grammars to analyze syntax.
This is the presentation on Syntactic Analysis in NLP.It includes topics like Introduction to parsing, Basic parsing strategies, Top-down parsing, Bottom-up
parsing, Dynamic programming – CYK parser, Issues in basic parsing methods, Earley algorithm, Parsing
using Probabilistic Context Free Grammars.
1) LR(0) parsers use left-to-right, rightmost derivations with 0-token lookahead to parse context-free grammars deterministically.
2) The states of the LR(0) automaton are sets of parsing items that indicate the progress of recognizing productions.
3) Parsing tables are constructed from the automaton to specify the shift and reduce actions and state transitions based on the next input symbol.
Syntax analysis involves converting a stream of tokens into a parse tree using grammar production rules. It recognizes the structure of a program using grammar rules. There are three main types of parsers - top-down, bottom-up, and universal. Top-down parsers build parse trees from the top-down while bottom-up parsers work from the leaves up. Bottom-up shift-reduce parsing uses a stack and input buffer, making shift and reduce decisions based on parser states to replace substrings matching productions. The largest class of grammars bottom-up parsers can handle is LR grammars.
This presentation discusses the following Fuzzy logic concepts:
Introduction
Crisp Variables
Fuzzy Variables
Fuzzy Logic Operators
Fuzzy Control
Case Study
This slide is prepared By these following Students of Dept. of CSE JnU, Dhaka. Thanks To: Nusrat Jahan, Arifatun Nesa, Fatema Akter, Maleka Khatun, Tamanna Tabassum.
The document discusses ambiguous and unambiguous context-free grammars (CFGs). CFGs are classified as ambiguous if a string has two or more possible parse trees, and unambiguous otherwise. Several examples are provided to illustrate ambiguous grammars that have multiple derivations for strings, such as grammars generating expressions. Unambiguous grammars are also exemplified, including one for the language of strings with a's. The document concludes with references for further reading on ambiguity in grammars and automata theory.
A grammar is said to be regular, if the production is in the form -
A → αB,
A -> a,
A → ε,
for A, B ∈ N, a ∈ Σ, and ε the empty string
A regular grammar is a 4 tuple -
G = (V, Σ, P, S)
V - It is non-empty, finite set of non-terminal symbols,
Σ - finite set of terminal symbols, (Σ ∈ V),
P - a finite set of productions or rules,
S - start symbol, S ∈ (V - Σ)
It is on simple topic of compiler but first and foremost important topic of compiler. For Lexical Analyzing we coded in C language. So it is easy to understand .
This document describes a course on Theory of Computation. It provides information on the course objectives, which are to understand language hierarchies, construct automata for patterns, design context-free grammars, understand Turing machines and their capabilities, and understand undecidable and NP problems. It outlines 5 units that will be covered: automata fundamentals, regular expressions and languages, context-free grammar and languages, properties of context-free languages, and undecidability. It also provides the course outcomes and lists reference textbooks. The document then begins describing some key concepts from Unit 1, including formal proofs, additional proof forms, inductive proofs, and an introduction to finite automata.
FellowBuddy.com is an innovative platform that brings students together to share notes, exam papers, study guides, project reports and presentation for upcoming exams.
We connect Students who have an understanding of course material with Students who need help.
Benefits:-
# Students can catch up on notes they missed because of an absence.
# Underachievers can find peer developed notes that break down lecture and study material in a way that they can understand
# Students can earn better grades, save time and study effectively
Our Vision & Mission – Simplifying Students Life
Our Belief – “The great breakthrough in your life comes when you realize it, that you can learn anything you need to learn; to accomplish any goal that you have set for yourself. This means there are no limits on what you can be, have or do.”
Like Us - https://www.facebook.com/FellowBuddycom
6-Role of Parser, Construction of Parse Tree and Elimination of Ambiguity-06-...movocode
This document discusses the role of a parser in compiler design. It begins by explaining that a parser obtains tokens from a lexical analyzer and generates a syntax tree while also reporting any syntax errors. It then discusses the two main types of parsers: top-down and bottom-up. The document goes on to define context-free grammars and their components such as terminals, non-terminals, the start symbol, and productions. It also discusses the concepts of derivations, leftmost and rightmost derivations, and parsing ambiguities that can arise from grammars. Finally, it covers techniques for eliminating left recursion from grammars.
The document discusses N-gram language models, which assign probabilities to sequences of words. An N-gram is a sequence of N words, such as a bigram (two words) or trigram (three words). The N-gram model approximates the probability of a word given its history as the probability given the previous N-1 words. This is called the Markov assumption. Maximum likelihood estimation is used to estimate N-gram probabilities from word counts in a corpus.
This presentation discusses context-free grammars. It defines context-free grammars and provides an example. It also discusses parse trees, including how they are generated and different types (top-down and bottom-up). Examples are provided to demonstrate leftmost and rightmost derivations and parse trees. The document concludes that the grammar presented, with production rules of X → X+X | X*X |X| a, is ambiguous as there are two possible parse trees for the string "a+a*a".
The document outlines the 5 phases of natural language processing (NLP):
1. Morphological analysis breaks text into paragraphs, sentences, words and assigns parts of speech.
2. Syntactic analysis checks grammar and parses sentences.
3. Semantic analysis focuses on literal word and phrase meanings.
4. Discourse integration considers the effect of previous sentences on current ones.
5. Pragmatic analysis discovers intended effects by applying cooperative dialogue rules.
Machine learning models involve a bias-variance tradeoff, where increased model complexity can lead to overfitting training data (high variance) or underfitting (high bias). Bias measures how far model predictions are from the correct values on average, while variance captures differences between predictions on different training data. The ideal model has low bias and low variance, accurately fitting training data while generalizing to new examples.
This document provides an overview of a compiler design course, including prerequisites, textbook, course outline, and introductions to key compiler concepts. The course outline covers topics such as lexical analysis, syntax analysis, parsing techniques, semantic analysis, intermediate code generation, code optimization, and code generation. Compiler design involves translating a program from a source language to a target language. Key phases of compilation include lexical analysis, syntax analysis, semantic analysis, intermediate code generation, code optimization, and code generation. Parsing techniques can be top-down or bottom-up.
This seminar presentation provides an overview of YACC (Yet Another Compiler Compiler). It discusses what compilers do, the structure of compilers including scanners, parsers, semantic routines, code generators and optimizers. It then reviews parsers and how YACC works by taking a grammar specification and generating C code for a parser. YACC declarations and commands are also summarized.
Random Forest Algorithm widespread popularity stems from its user-friendly nature and adaptability, enabling it to tackle both classification and regression problems effectively. The algorithm’s strength lies in its ability to handle complex datasets and mitigate overfitting, making it a valuable tool for various predictive tasks in machine learning.
One of the most important features of the Random Forest Algorithm is that it can handle the data set containing continuous variables, as in the case of regression, and categorical variables, as in the case of classification. It performs better for classification and regression tasks. In this tutorial, we will understand the working of random forest and implement random forest on a classification task.
The document discusses syntax analysis and parsing. It defines a syntax analyzer as creating the syntactic structure of a source program in the form of a parse tree. A syntax analyzer, also called a parser, checks if a program satisfies the rules of a context-free grammar and produces the parse tree if it does, or error messages otherwise. It describes top-down and bottom-up parsing methods and how parsers use grammars to analyze syntax.
This is the presentation on Syntactic Analysis in NLP.It includes topics like Introduction to parsing, Basic parsing strategies, Top-down parsing, Bottom-up
parsing, Dynamic programming – CYK parser, Issues in basic parsing methods, Earley algorithm, Parsing
using Probabilistic Context Free Grammars.
1) LR(0) parsers use left-to-right, rightmost derivations with 0-token lookahead to parse context-free grammars deterministically.
2) The states of the LR(0) automaton are sets of parsing items that indicate the progress of recognizing productions.
3) Parsing tables are constructed from the automaton to specify the shift and reduce actions and state transitions based on the next input symbol.
Syntax analysis involves converting a stream of tokens into a parse tree using grammar production rules. It recognizes the structure of a program using grammar rules. There are three main types of parsers - top-down, bottom-up, and universal. Top-down parsers build parse trees from the top-down while bottom-up parsers work from the leaves up. Bottom-up shift-reduce parsing uses a stack and input buffer, making shift and reduce decisions based on parser states to replace substrings matching productions. The largest class of grammars bottom-up parsers can handle is LR grammars.
A parser is a program component that breaks input data into smaller elements according to the rules of a formal grammar. It builds a parse tree representing the syntactic structure of the input based on these grammar rules. There are two main types of parsers: top-down parsers start at the root of the parse tree and work downward, while bottom-up parsers start at the leaves and work upward. Parser generators use attributes like First and Follow to build parsing tables for predictive parsers like LL(1) parsers, which parse input from left to right based on a single lookahead token.
Syntactic specification is concerned with the structure and organization of t...vijaya603274
Syntactic specification is concerned with the structure and organization of the symbols, words, and phrases that make up a language. It defines the rules for constructing valid sentences, expressions, or messages.
This document discusses top-down parsing and different types of top-down parsers, including recursive descent parsers, predictive parsers, and LL(1) grammars. It explains how to build predictive parsers without recursion by using a parsing table constructed from the FIRST and FOLLOW sets of grammar symbols. The key steps are: 1) computing FIRST and FOLLOW, 2) filling the predictive parsing table based on FIRST/FOLLOW, 3) using the table to parse inputs in a non-recursive manner by maintaining the parser's own stack. An example is provided to illustrate constructing the FIRST/FOLLOW sets and parsing table for a sample grammar.
The document discusses syntax-directed translation and intermediate code generation in compilers. It describes how syntax-directed definitions associate semantic rules with context-free grammar productions to evaluate attributes during parsing. These attributes can generate intermediate code, update symbol tables, and perform other tasks. Syntax-directed translation builds an abstract syntax tree while intermediate code generation converts this to forms like postfix notation, three-address code, or quadruples for further optimization before final code generation.
The document discusses syntax-directed translation and intermediate code generation in compilers. It covers syntax-directed definitions and translation schemes for associating semantic rules with context-free grammar productions. Attribute grammars are defined where semantic rules only evaluate attributes without side effects. Syntax-directed translation builds an abstract syntax tree where each node represents a language construct. Intermediate representations like postfix notation, three-address code, and quadruples are discussed for implementing syntax trees and facilitating code optimization during compilation.
The document discusses syntax-directed translation and intermediate code generation in compilers. It covers syntax-directed definitions and translation schemes for associating semantic rules with context-free grammar productions. Attribute grammars are defined where semantic rules only evaluate attributes without side effects. Syntax-directed translation builds an abstract syntax tree where each node represents a language construct. Intermediate representations like postfix notation, three-address code, and quadruples are discussed for implementing syntax trees and facilitating code optimization during compilation.
Top-down parsing begins with the root symbol and uses productions to construct the parse tree from the top down. It repeats selecting a production for the current non-terminal and adding symbols to the parse tree until the input is fully parsed or a mismatch requires backtracking. Recursive descent parsing is a type of top-down parsing where each non-terminal's productions are represented by recursive functions attempting productions left-to-right with backtracking. Left recursion in grammars prevents recursive descent parsing from terminating, so left-recursive productions must be eliminated before using this approach.
The document discusses different types of parsing including:
1) Top-down parsing which starts at the root node and builds the parse tree recursively, requiring backtracking for ambiguous grammars.
2) Bottom-up parsing which starts at the leaf nodes and applies grammar rules in reverse to reach the start symbol using shift-reduce parsing.
3) LL(1) and LR parsing which are predictive parsing techniques using parsing tables constructed from FIRST and FOLLOW sets to avoid backtracking.
Predictive parsing is a technique for parsing context-free grammars where the parser predicts the next production to use based on looking ahead at upcoming tokens. It works for LL(1) grammars, where the production can be determined uniquely from the next token. The parsing process involves building a parsing table from the grammar's first and follow sets and using that table to guide the parser's actions. When an error is detected, various recovery techniques like panic mode or inserting error productions can be used to try to continue parsing.
This document describes the structure and components of a simple one-pass compiler to generate code for the Java Virtual Machine (JVM). It discusses lexical analysis, syntax-directed translation, predictive parsing, and code generation. The compiler consists of a lexical analyzer, syntax-directed translator using a context-free grammar, and parser/code generator to develop for the translator. It provides examples of attribute grammars, translation schemes, and techniques for handling ambiguity, precedence, and left recursion in parsing.
The document discusses LL(1) parsers and table-driven parsing. It defines LL(1) parsers as parsers that can be constructed to parse LL(1) grammars by looking ahead 1 symbol. Table-driven parsers use parsing tables generated from the grammar to parse inputs. The document provides details on computing FIRST and FOLLOW sets, building LL(1) parsing tables from grammars, and provides an example of a table-driven parse of an expression grammar.
Here is a recursive function to check if a list contains an element:
(defun contains (element list)
(cond ((null list) nil)
((equal element (car list)) t)
(t (contains element (cdr list)))))
To check the guest list:
(contains 'robocop guest-list)
This function:
1. Base case: If list is empty, element is not contained - return nil
2. Check if element equals car of list - if so, return t
3. Otherwise, recursively call contains on element and cdr of list
So it will recursively traverse the list until it finds a match or reaches empty list.
This document discusses syntax analysis in compilers. It covers the role of parsers, different types of parsers like top-down and bottom-up parsers, context free grammars, derivations, parse trees, ambiguity, left recursion elimination, left factoring, recursive descent parsing, LL(1) grammars, construction of parsing tables, and error recovery techniques for predictive parsing.
This document provides an overview of syntax analysis in compiler design. It discusses context-free grammars, top-down parsing including recursive descent and LL(1) parsing, and bottom-up parsing including LR parsing. It describes the key concepts of context-free grammars, ambiguous and unambiguous grammars. It explains top-down parsing as constructing a parse tree from the root node down and bottom-up parsing as building the tree from the leaf nodes up. It discusses the closure and goto operations used in LR parsing and describes the differences between LR(0), SLR, CLR, and LALR parsing techniques.
Tesia Dobrydnia brings her many talents to her career as a chemical engineer in the oil and gas industry. With the same enthusiasm she puts into her work, she engages in hobbies and activities including watching movies and television shows, reading, backpacking, and snowboarding. She is a Relief Senior Engineer for Chevron and has been employed by the company since 2007. Tesia is considered a leader in her industry and is known to for her grasp of relief design standards.
Kevin Corke Spouse Revealed A Deep Dive Into His Private Life.pdfMedicoz Clinic
Kevin Corke, a respected American journalist known for his work with Fox News, has always kept his personal life away from the spotlight. Despite his public presence, details about his spouse remain mostly private. Fans have long speculated about his marital status, but Corke chooses to maintain a clear boundary between his professional and personal life. While he occasionally shares glimpses of his family on social media, he has not publicly disclosed his wife’s identity. This deep dive into his private life reveals a man who values discretion, keeping his loved ones shielded from media attention.
"The Enigmas of the Riemann Hypothesis" by Julio ChaiJulio Chai
In the vast tapestry of the history of mathematics, where the brightest minds have woven with threads of logical reasoning and flash-es of intuition, the Riemann Hypothesis emerges as a mystery that chal-lenges the limits of human understanding. To grasp its origin and signif-icance, it is necessary to return to the dawn of a discipline that, like an incomplete map, sought to decipher the hidden patterns in numbers. This journey, comparable to an exploration into the unknown, takes us to a time when mathematicians were just beginning to glimpse order in the apparent chaos of prime numbers.
Centuries ago, when the ancient Greeks contemplated the stars and sought answers to the deepest questions in the sky, they also turned their attention to the mysteries of numbers. Pythagoras and his followers revered numbers as if they were divine entities, bearers of a universal harmony. Among them, prime numbers stood out as the cornerstones of an infinite cathedral—indivisible and enigmatic—hiding their ar-rangement beneath a veil of apparent randomness. Yet, their importance in building the edifice of number theory was already evident.
The Middle Ages, a period in which the light of knowledge flick-ered in rhythm with the storms of history, did not significantly advance this quest. It was the Renaissance that restored lost splendor to mathe-matical thought. In this context, great thinkers like Pierre de Fermat and Leonhard Euler took up the torch, illuminating the path toward a deeper understanding of prime numbers. Fermat, with his sharp intuition and ability to find patterns where others saw disorder, and Euler, whose overflowing genius connected number theory with other branches of mathematics, were the architects of a new era of exploration. Like build-ers designing a bridge over an unknown abyss, their contributions laid the groundwork for later discoveries.
Forensic Science – Digital Forensics – Digital Evidence – The Digital Forensi...ManiMaran230751
Forensic Science – Digital Forensics – Digital Evidence – The Digital Forensics Process – Introduction – The
Identification Phase – The Collection Phase – The Examination Phase – The Analysis Phase – The
Presentation Phase.
UNIT-5-PPT Computer Control Power of Power SystemSridhar191373
Introduction
Conceptual Model of the EMS
EMS Functions and SCADA Applications.
Time decomposition of the power system operation.
Open Distributed system in EMS
OOPS
UNIT-4-PPT UNIT COMMITMENT AND ECONOMIC DISPATCHSridhar191373
Statement of unit commitment problem-constraints: spinning reserve, thermal unit constraints, hydro constraints, fuel constraints and other constraints. Solution methods: priority list methods, forward dynamic programming approach. Numerical problems only in priority list method using full load average production cost. Statement of economic dispatch problem-cost of generation-incremental cost curve –co-ordination equations without loss and with loss- solution by direct method and lamda iteration method (No derivation of loss coefficients)
This presentation provides a detailed overview of air filter testing equipment, including its types, working principles, and industrial applications. Learn about key performance indicators such as filtration efficiency, pressure drop, and particulate holding capacity. The slides highlight standard testing methods (e.g., ISO 16890, EN 1822, ASHRAE 52.2), equipment configurations (such as aerosol generators, particle counters, and test ducts), and the role of automation and data logging in modern systems. Ideal for engineers, quality assurance professionals, and researchers involved in HVAC, automotive, cleanroom, or industrial filtration systems.
Department of Environment (DOE) Mix Design with Fly Ash.MdManikurRahman
Concrete Mix Design with Fly Ash by DOE Method. The Department of Environmental (DOE) approach to fly ash-based concrete mix design is covered in this study.
The Department of Environment (DOE) method of mix design is a British method originally developed in the UK in the 1970s. It is widely used for concrete mix design, including mixes that incorporate supplementary cementitious materials (SCMs) such as fly ash.
When using fly ash in concrete, the DOE method can be adapted to account for its properties and effects on workability, strength, and durability. Here's a step-by-step overview of how the DOE method is applied with fly ash.
DIY Gesture Control ESP32 LiteWing Drone using PythonCircuitDigest
Build a gesture-controlled LiteWing drone using ESP32 and MPU6050. This presentation explains components, circuit diagram, assembly steps, and working process.
Read more : https://circuitdigest.com/microcontroller-projects/diy-gesture-controlled-drone-using-esp32-and-python-with-litewing
Ideal for DIY drone projects, robotics enthusiasts, and embedded systems learners. Explore how to create a low-cost, ESP32 drone with real-time wireless gesture control.
This presentation provides a comprehensive overview of air filter testing equipment and solutions based on ISO 5011, the globally recognized standard for performance testing of air cleaning devices used in internal combustion engines and compressors.
Key content includes:
BEC602-Module-3-1_Notes.pdf. Vlsi design and testing notesVarshithaP6
Compiler: Syntax Analysis
1. Syllabus
• Syntax Analysis - CFG, top-down and bottom-
up parsers, RDP, Predictive parser, SLR,LR(1),
LALR parsers, using ambiguous grammar, Error
detection and recovery, automatic
construction of parsers using YACC,
Introduction to Semantic analysis-Need of
semantic analysis, type checking and type
conversion.
1- By Jaydeep Patil AISSMS's IOIT Pune
3. Grammar
• A Set of formal rules for generating syntactically correct
sentence.
• It is defined by tuple G(V,T,P,S)
– V- Variables
– T- Terminals
– P-Production
– S-Start Symbol(variable)
• Terminal-{a,b,c,…..z,0-9}
• Nonterminal or Variable-{A-Z}
• Rule : LHS of production should at least contain one
non-terminal that is variable.
3- By Jaydeep Patil AISSMS's IOIT Pune
5. CFG
• RULE: 1. Every Production of the form
𝐴 → α
A any Variable, α any terminal
2. α → β
On LHS of Production there has to be
only non-terminal, Variable not string
CFL(Context Free Language)-> A Set of
Sentences derived from start symbol of CGF is
called CFL.
6- By Jaydeep Patil AISSMS's IOIT Pune
6. Leftmost and Rightmost Derivations
E->E+E
E->E*E
E->id
• Derive Id+id*id
7- By Jaydeep Patil AISSMS's IOIT Pune
8. Ambiguity
• A grammar that produces more than one
parse tree for some sentence is said to be
ambiguous. Put another way, an ambiguous
grammar is one that produces more than one
leftmost derivation or more than one
rightmost derivation for the same sentence.
9- By Jaydeep Patil AISSMS's IOIT Pune
10. Left Recursion
• A grammar is left recursive if it has a nonterminal A such that
there is a derivation
A -> Aa
for some string a.
• Top-down parsing methods cannot handle left-recursive
grammars, so a transformation is needed to eliminate left
recursion.
A -> Aa I b
A-> bA’
A’->aA’/e
11- By Jaydeep Patil AISSMS's IOIT Pune
11. Left Factoring
• Left factoring is a grammar transformation that is useful for producing a
grammar suitable for predictive, or top-down, parsing. When the choice
between two alternative A-productions is not clear, we may be able to
rewrite the productions to defer the decision until enough of the input has
been seen that we can make the right choice.
• For example, if we have the two production
A -> ab1 I ab2
A-> aA’
A’-> b1|b2
12- By Jaydeep Patil AISSMS's IOIT Pune
13. Top Down Parsing
• Top-down parsing can be viewed as the problem of
constructing a parse tree for the input string, starting from the
root and creating the nodes of the parse tree in preorder.
Equivalently, top-down parsing can be viewed as finding a
leftmost derivation for an input string.
14- By Jaydeep Patil AISSMS's IOIT Pune
14. Recursive-Descent Parsing
• A recursive-descent parsing program consists
of a set of procedures, one for each
nonterminal. Execution begins with the
procedure for the start symbol, which halts
and announces success if its procedure body
scans the entire input string.
15- By Jaydeep Patil AISSMS's IOIT Pune
16. Recursive-Descent Parsing
• General recursive-descent may require
backtracking; that is, it may require repeated
scans over the input. However, backtracking is
rarely needed to parse programming language
constructs, so backtracking parsers are not
seen frequently.
17- By Jaydeep Patil AISSMS's IOIT Pune
18. Recursive-Descent Parsing
• A left-recursive grammar can cause a
recursive-descent parser, even one with
backtracking, to go into an infinite loop. That
is, when we try to expand a nonterminal A, we
may eventually find ourselves again trying to
expand A without having consumed any input.
19- By Jaydeep Patil AISSMS's IOIT Pune
19. FIRST and FOLLOW
• The construction of both top-down and
bottom-up parsers is aided by two functions,
FIRST and FOLLOW, associated with a
grammar G. During topdown parsing, FIRST
and FOLLOW allow us to choose which
production to apply, based on the next input
symbol. During panic-mode error recovery,
sets of tokens produced by FOLLOW can be
used as synchronizing tokens.
20- By Jaydeep Patil AISSMS's IOIT Pune
20. FIRST
• First is a function which gives the set of terminals
that begins the string derived from production
rules.
• Rules:
1. If x is a terminal then first(x)=x.
2. If X->e is a production, then add e to the set of
first[x].
3. If X is non terminal then,
3.a) If X->Y, first (Y) is an element of the set of first(x).
3.b) If first(Y) has e as an element & X->YZ then
first(x)=first(Y)-e U first(z)
21- By Jaydeep Patil AISSMS's IOIT Pune
21. Follow
• Follow is a function which gives set of terminals that
can appear immediately to the right of given symbol.
• Rules:
22- By Jaydeep Patil AISSMS's IOIT Pune
36. LL ( 1 ) Grammars
• Predictive parsers, that is, recursive-descent parsers
needing no backtracking, can be constructed for a class
of grammars called LL(I) , The first "L" in LL(1) stands
for scanning the input from left to right, the second "L"
for producing a leftmost derivation, and the “1" for
using one input symbol of lookahead at each step to
make parsing action decisions.
• The class of LL(1) grammars is rich enough to cover
most programming constructs, although care is needed
in writing a suitable grammar for the source language .
For example, no left-recursive or ambiguous grammar
can be LL(1) .
37- By Jaydeep Patil AISSMS's IOIT Pune
38. Grammar is LL(1)(No Multiple Entries)
39- By Jaydeep Patil AISSMS's IOIT Pune
39. Grammar is Not LL(1)(Multiple Entries)
40- By Jaydeep Patil AISSMS's IOIT Pune
40. Nonrecursive Predictive Parsing
• A non recursive predictive parser can be built
by maintaining a stack explicitly, rather than
implicitly via recursive calls. The parser mimics
a leftmost derivation. If w is the input that has
been matched so far , then the stack holds a
sequence of grammar symbols.
41- By Jaydeep Patil AISSMS's IOIT Pune
43. • If X=a=$ the parser halts & announces successful
completion of parsing
• If X=a|=$ the parser pops X the stack and advance the
i/p pointer to the next i/p symbol.
• If x is non terminal the program consults entry M[X,a]
of the parsing table M. This entry will either on X
production of the grammar or an error entry. If for
example m[x,a]->{UVW} the parser replaces x on the
top of stack by WVU(with U on top of stack). As output
we shall assume that the parser joust points to the
production used.
45- By Jaydeep Patil AISSMS's IOIT Pune
46. Bottom-Up Parsing
• A bottom-up parse corresponds to the
construction of a parse tree for an input string
beginning at the leaves (the bottom) and
working up towards the root (the top) .
48- By Jaydeep Patil AISSMS's IOIT Pune
48. Reductions
• We can think of bottom-up parsing as the
process of "reducing" a string w to the start
symbol of the grammar. At each reduction
step, a specific substring matching the body of
a production is replaced by the nonterminal at
the head of that production.
• The key decisions during bottom-up parsing
are about when to reduce and about what
production to apply, as the parse proceeds.
50- By Jaydeep Patil AISSMS's IOIT Pune
49. • The goal of bottom-up parsing is therefore to
construct a derivation in reverse. The
following derivation corresponds to the parse
in
• E => T => T * F => T * id => F * id => id * id
• This derivation is in fact a rightmost
derivation.
51- By Jaydeep Patil AISSMS's IOIT Pune
50. Handle
• Bottom-up parsing during a left-to-right scan
of the input constructs a rightmost derivation
in reverse. Informally, a "handle" is a substring
that matches the body of a production, and
whose reduction represents one step along
the reverse of a rightmost derivation.
52- By Jaydeep Patil AISSMS's IOIT Pune
51. Shift-Reduce Parsing
• Shift-reduce parsing is a form of bottom-up parsing in
which a stack holds grammar symbols and an input
buffer holds the rest of the string to be parsed.
• As we shall see, the handle always appears at the top of
the stack just before it is identified as the handle.
• We use $ to mark the bottom of the stack and also the
right end of the input. Conventionally, when discussing
bottom-up parsing, we show the top of the stack on the
right, rather than on the left as we did for top-down
parsing. Initially, the stack is empty, and the string w is
on the input, as follows:
55- By Jaydeep Patil AISSMS's IOIT Pune
52. • During a left-to-right scan of the input string,
the parser shifts zero or more input symbols
onto the stack, until it is ready to reduce a
string β of grammar symbols on top of the
stack. It then reduces β to the head of the
appropriate production. The parser repeats
this cycle until it has detected an error or until
the stack contains the start symbol and the
input is empty:
56- By Jaydeep Patil AISSMS's IOIT Pune
54. LR Parsing: Simple LR
• The 'most prevalent type of bottom-up parser
today is based on a concept called LR(k) parsing;
the "L" is for left-to-right scanning of the input,
the "R" for constructing a rightmost derivation in
reverse, and the k for the number of input
symbols of lookahead that are used in making
parsing decisions. The cases k = 0 or k = 1 are of
practical interest, and we shall only consider LR
parsers with k <= 1 here. When (k) is omitted, k is
assumed to be 1 .
58- By Jaydeep Patil AISSMS's IOIT Pune
55. Why LR Parsers
• LR parsers are table-driven, much like the
nonrecursive LL parsers. A grammar for which
we can construct a parsing table using one of
the methods in this section and the next is
said to be an LR grammar. Intuitively, for a
grammar to be LR it is sufficient that a left-to-
right shift-reduce parser be able to recognize
handles of right- sentential forms when they
appear on top of the stack.
59- By Jaydeep Patil AISSMS's IOIT Pune
57. • The principal drawback of the LR method is that it is too
much work to construct an LR parser by hand for a typical
programming-language grammar. A specialized tool, an LR
parser generator, is needed.
• Fortunately, many such generators are available, and we
shall discuss one of the most commonly used ones, Yacc .
• Such a generator takes a context-free grammar and
automatically produces a parser for that grammar. If the
grammar contains ambiguities or other constructs that are
difficult to parse in a left-to-right scan of the input, then the
parser generator locates these constructs and provides
detailed diagnostic messages.
61- By Jaydeep Patil AISSMS's IOIT Pune
58. Items and the LR(O) Automaton
62- By Jaydeep Patil AISSMS's IOIT Pune
59. Augmented grammar
• If G is a grammar with start symbol S, then G' ,
the augmented grammar for G, is G with a ne
• start symbol S' and production S' -> S. The
purpose of this new starting production is to
indicate to the parser when it should stop
parsing and announce acceptance of the
input. That is, acceptance occurs when and
only when the parser is about to reduce by
• S' -> S.
63- By Jaydeep Patil AISSMS's IOIT Pune
72. Operator Precedence Parsing
• Operator Grammar: For Small but important
class of grammar, we can easily construct
efficient shift reduce parsers by hand.
Operator Grammars have the property that no
production right side is empty or has two
adjacent non-terminals.
76- By Jaydeep Patil AISSMS's IOIT Pune
73. • Eg: E-> EAE/ (E)/ -E/id
• A->+/-/|/*/
• The above grammar is not operator grammar
but we can readjust the grammar.
77- By Jaydeep Patil AISSMS's IOIT Pune
74. • In Operator Precedence Parsing we define
three disjoint precedence relations <· , =· ,·>
between certain pair of terminals. This
precedence relations guide the selection of
handle & have the following meaning
78- By Jaydeep Patil AISSMS's IOIT Pune
75. • Basic Principle
• Having precedence relations allows identifying handles as follows:
• 1. Scan the string from left until seeing ·> and put a pointer.
• 2. Scan backwards the string from right to left until seeing <·
• 3. Everything between the two relations <· and ·> forms the handle
• 4. Replace handle with the head of the production.
79- By Jaydeep Patil AISSMS's IOIT Pune
77. Conflicts in LR Parsing
• Every SLR grammar is unambiguous, but every unambiguous
grammar is not a SLR grammar.
81- By Jaydeep Patil AISSMS's IOIT Pune
78. shift/reduce and reduce/reduce
conflicts
• If a state does not know whether it will make a shift
operation or reduction for a terminal, we say that there
is a shift/reduce conflict.
• If a state does not know whether it will make a
reduction operation using the production rule i or j
for a terminal, we say that there is a reduce/reduce
conflict.
• If the SLR parsing table of a grammar G has a conflict,
we say that that grammar is not SLR grammar.
82- By Jaydeep Patil AISSMS's IOIT Pune
81. Using Ambiguous Grammars
• All grammars used in the construction of LR-parsing
tables must be un-ambiguous.
• Can we create LR-parsing tables for ambiguous
grammars ?
– Yes, but they will have conflicts.
– We can resolve these conflicts in favor of one of them to disambiguate the grammar.
– At the end, we will have again an unambiguous grammar.
• Why we want to use an ambiguous grammar?
– Some of the ambiguous grammars are much natural, and a corresponding unambiguous
grammar can be very complex.
– Usage of an ambiguous grammar may eliminate unnecessary reductions.
• Ex.
E E+T | T
E E+E | E*E | (E) | id T T*F | F
F (E) | id
85- By Jaydeep Patil AISSMS's IOIT Pune
82. Sets of LR(0) Items for Ambiguous
Grammar
I0: E’ .E
E .E+E
E .E*E
E .(E)
E .id
I1: E’ E.E E .+E
E E .*E
I2: E (.E)
E .E+E
E .E*E
E .(E)
E .id
I3: E id.
I4: E E +.E
E .E+E
E .E*E
E .(E)
E .id
I5: E E *.E
E .E+E
E .E*E
E .(E)
E .id
I6: E (E.)
E E.+E
E E.*E
I7: E E+E.E E.+E
E E.*E
I8: E E*E.E E.+E
E E.*E
I9: E (E).
I5
)
E
E
E
E
*
+
+
+
+
*
*
*
(
(
(
(
id
id
id
id
I4
I2
I2
I3
I3
I4
I4
I5
I5
86- By Jaydeep Patil AISSMS's IOIT Pune
89. Error Recovery in LR Parsing
• An LR parser will detect an error when it consults the
parsing action table and finds an error entry. All empty
entries in the action table are error entries.
• Errors are never detected by consulting the goto table.
• An LR parser will announce error as soon as there is no
valid continuation for the scanned portion of the input.
• A canonical LR parser (LR(1) parser) will never make
even a single reduction before announcing an error.
• The SLR and LALR parsers may make several reductions
before announcing an error.
• But, all LR parsers (LR(1), LALR and SLR parsers) will
never shift an erroneous input symbol onto the stack.
93- By Jaydeep Patil AISSMS's IOIT Pune
90. ERROR RECOVERY IN LR PARSING
• An LR Parser will detect an error when it consults
parsing table and finds an error entry. A canonical
parser will never make even a single reduction before
announcing an error. The SLR and LALR parsers may
take several reductions before announcing an error,
but they will never shift an erroneous input into the
stack..
• We can implement two modes of recovery :
94- By Jaydeep Patil AISSMS's IOIT Pune
91. Panic Mode
• We scan down the stack until a state s with a goto
on a particular non-terminal A is found. Zero or more
input symbols are then discarded until a symbol a is
found that can legitimately follow A. The parser then
stack the state goto[ s, A] and resume normal
parsing. Normally there may be many choices for the
non terminal A. Normally these would be non-
terminals representing major program pieces, such
as an expression, statement, or block.
95- By Jaydeep Patil AISSMS's IOIT Pune
92. Phrase Level Recovery
• It is implemented by examining each error
entry in the LR parsing table and deciding on
the basis of language the most likely program
error that give rise to that error entry in the LR
parsing table. An appropriate error procedure
than can be implemented; presumably the top
of the stack and/or first input symbols would
be modified in a way deemed appropriate for
each error.
96- By Jaydeep Patil AISSMS's IOIT Pune
93. • As an example consider the grammar (1).
E E + E | E * E | ( E ) | id ---- (1)
The parsing table contains error routines that
have effect of detecting error before any
shift move takes place.
97- By Jaydeep Patil AISSMS's IOIT Pune
95. Error routines : e1
• This routine is called from states 0,2,4 and 5,
all of which the beginning of the operand,
either an id of left parenthesis. Instead an
operator, + or *, or the end of input was
found.
• Action: Push an imaginary id on to the stack
and cover it with a state 3. (the goto of the
states 0, 2, 4 and 5)
• Print: Issue diagnostic “missing operand”
99- By Jaydeep Patil AISSMS's IOIT Pune
96. Error routines : e2
• This routine is called from states 0, 1, 2, 4 and
5 on the finding a right parenthesis.
• Action: Remove the right parenthesis from the
input
• Print: Issue diagnostic “Unbalanced right
parenthesis”
100- By Jaydeep Patil AISSMS's IOIT Pune
97. Error routines : e3
• This routine is called from states 1 or 6 when
expecting an operator, and an id or right
parenthesis is found.
• Action: Push + onto the stack and cover it with
state 4.
• Print: Issue diagnostic “Missing operator”
101- By Jaydeep Patil AISSMS's IOIT Pune
98. Error routines : e4
• This routine is called from state 6 when the
end of input is found while expecting operator
or a right parenthesis.
• Action: Push a right parenthesis onto the stack
and cover it with a state 9.
• Print: Issue diagnostic “Missing right
parenthesis”
102- By Jaydeep Patil AISSMS's IOIT Pune
99. Automatic construction of parsers
(YACC), YACC specifications.
103- By Jaydeep Patil AISSMS's IOIT Pune
100. 104
Automatic construction of parsers
(YACC), YACC specifications.
• Two classical tools for compilers:
– Lex: A Lexical Analyzer Generator
– Yacc: “Yet Another Compiler Compiler” (Parser Generator)
• Lex creates programs that scan your tokens one by one.
• Yacc takes a grammar (sentence structure) and generates a
parser.
Lex Yacc
yylex() yyparse()
Lexical Rules Grammar Rules
Input Parsed Input
- By Jaydeep Patil AISSMS's IOIT Pune
101. 105
Automatic construction of parsers
(YACC), YACC specifications.
• Lex and Yacc generate C code for your analyzer & parser.
Lex Yacc
yylex() yyparse()
Lexical Rules Grammar Rules
Input
Parsed
Input
C code C code
C code C code
Lexical Analyzer
(Tokenizer)
Parser
char
stream
token
stream
- By Jaydeep Patil AISSMS's IOIT Pune
102. 106
Automatic construction of parsers
(YACC), YACC specifications.
• Often, instead of the standard Lex and Yacc,
Flex and Bison are used:
– Flex: A fast lexical analyzer
– (GNU) Bison: A drop-in replacement for (backwards
compatible with) Yacc
• Byacc is Berkeley implementation of Yacc (so it
is Yacc).
• Resources:
– http://en.wikipedia.org/wiki/Flex_lexical_analyser
– http://en.wikipedia.org/wiki/GNU_Bison
• The Lex & Yacc Page (manuals, links):
– http://dinosaur.compilertools.net/
- By Jaydeep Patil AISSMS's IOIT Pune
103. 107
Automatic construction of parsers
(YACC), YACC specifications.
• Yacc is not a new tool, and yet, it is still used in many
projects.
• Yacc syntax is similar to Lex/Flex at the top level.
• Lex/Flex rules were regular expression – action pairs.
• Yacc rules are grammar rule – action pairs.
declarations
%%
rules
%%
programs
- By Jaydeep Patil AISSMS's IOIT Pune
105. • Declaration Section
• There are two sections in the declarations part of a Yacc program;
both are optional. In the first section, we put ordinary C
declarations, delimited by %{ and % }. Here we place declarations of
any temporaries used by the translation rules or procedures of the
second and third sections.
Ex. #include <ctype .h>
• The C preprocessor to include the standard header file <ctype . h>
that contains the predicate isdigit.
• Also in the declarations part are declarations of grammar tokens.
• %token DIGIT
• Tokens declared in this section can then be used in the second and
third parts of the Yacc specification. , If Lex is used to create the
lexical analyzer that passes token to the Yacc parser, then these
token declarations are also made available to the analyzer
generated by Lex.
109- By Jaydeep Patil AISSMS's IOIT Pune
106. • The Translation Rules Part
• In the part of the Yacc specification after the
first %% pair, we put the translation rules .
Each rule consists of a grammar production
and the associated semantic action. A set of
productions that we have been writing:
110- By Jaydeep Patil AISSMS's IOIT Pune
107. • In a Yacc production, unquoted strings of letters
and digits not declared to be tokens are taken to
be non terminals. A quoted single character, e.g. '
c' , is taken to be the terminal symbol c , as well
as the integer code for the token represented by
that character (i.e., Lex would return the
character code for ' c ‘ to the parser, as an
integer) . Alternative bodies can be separated by
a vertical bar, and a semicolon follows each head
with its alternatives and their semantic actions.
The first head is taken to be the start symbol.
111- By Jaydeep Patil AISSMS's IOIT Pune
108. • A Yacc semantic action is a sequence of C statements. In a
semantic action, the symbol $$ refers to the attribute value
associated with the nonterminal of the head, while $i refers to
the value associated with the ith grammar symbol (terminal or
nonterminal) of the body. The semantic action is performed
whenever we reduce by the associated production, so
normally the semantic action computes a value for $$ in
terms of the $i's. In the Yacc specification, we have written
the two E-productions
112- By Jaydeep Patil AISSMS's IOIT Pune
109. • Note that the nonterminal term in the first production is
the third grammar symbol of the body, while + is the
second. The semantic action associated with the first
production adds the value of the expr and the term of the
body and assigns the result as the value for the
nonterminal expr of the head. We have omitted the
semantic action for the second production altogether, since
copying the value is the default action for productions with
a single grammar symbol in the body. In general, { $$ = $ 1 ;
} is the default semantic action. Notice that we have added
a new starting production
• line : expr ' n ' { print f C " %dn" , $ 1 ) ; }
• to the Yacc specification. This production says that an input
to the desk calculator is to be an expression followed by a
newline character. The semantic action associated with this
production prints the decimal value of the expression
followed by a newline character.
113- By Jaydeep Patil AISSMS's IOIT Pune
110. • The Supporting C-Routines Part
• The third part of a Yacc specification consists of supporting C-
routines. A lexical analyzer by the name yylex() must be provided.
Using Lex to produce yylex() is a common choice; The lexical
analyzer yylex() produces tokens consisting of a token name and its
associated attribute value. If a token name such as DIGIT is
returned, the token name must be declared in the first section of
the Yacc specification.
• The attribute value associated with a token is communicated to the
parser through a Yacc-defined variable yylval. It reads input
characters one at a time using the C-function getchar() . If the
character is a digit, the value of the digit is stored in the variable
yylval, and the token name DIGIT is returned. Otherwise, the
character itself is returned as the token name.
114- By Jaydeep Patil AISSMS's IOIT Pune
112. yacc –d bas.y # create y.tab.h, y.tab.c
lex bas.l # create lex.yy.c
cc lex.yy.c y.tab.c –o bas.exe # compile/link
116- By Jaydeep Patil AISSMS's IOIT Pune
113. • Yacc reads the grammar descriptions in bas.y and generates a
syntax analyzer (parser), that includes function yyparse, in file
y.tab.c. The –d option causes yacc to generate definitions for
tokens and place them in file y.tab.h. Lex reads the pattern
descriptions in bas.l, includes file y.tab.h, and generates a
lexical analyzer, that includes function yylex, in file lex.yy.c.
• Finally, the lexer and parser are compiled and linked together
to create executable bas.exe. From main we call yyparse to
run the compiler. Function yyparse automatically calls yylex
to obtain each token.
117- By Jaydeep Patil AISSMS's IOIT Pune
114. • %token INTEGER
• This definition declares an INTEGER token. Yacc generates a parser in file y.tab.c
and an include file, y.tab.h:
• #ifndef YYSTYPE
• #define YYSTYPE int
• #endif
• #define INTEGER 258
• extern YYSTYPE yylval;
• Lex includes this file and utilizes the definitions for token values. To obtain tokens
yacc calls yylex. Function yylex has a return type of int that returns a token. Values
associated with the token are returned by lex in variable yylval. For example,
• [0-9]+ { yylval = atoi(yytext); return INTEGER; }
• would store the value of the integer in yylval, and return token INTEGER to yacc.
The type of yylval is determined by YYSTYPE. Since the default type is integer this
works well in this case. Token values 0-255 are reserved for character values. For
example, if you had a rule such as
• [-+] return *yytext; /* return operator */
• the character value for minus or plus is returned. Note that we placed the minus
sign first so that it wouldn’t be mistaken for a range designator. Generated token
values typically start around 258 because lex reserves several values for end-of-file
and error processing.
118- By Jaydeep Patil AISSMS's IOIT Pune
115. • By default yylval is of type int, but you can override that from the
YACC file by re#defining YYSTYPE.
• The Lexer needs to be able to access yylval. In order to do so, it
must be declared in the scope of the lexer as an extern variable.
The original YACC neglects to do this for you, so you should add the
following to your lexer, just beneath
• #include <y.tab.h>:
• extern YYSTYPE yylval;
• Bison does this for you automatically.
• #ifndef checks whether the given token has been #defined earlier
in the file or in an included file; if not, it includes the code between
it and the closing #else or, if no #else is present, #endif statement.
119- By Jaydeep Patil AISSMS's IOIT Pune
117. • Internally yacc maintains two stacks in memory; a
parse stack and a value stack. The parse stack
contains terminals and nonterminals that
represent the current parsing state. The value
stack is an array of YYSTYPE elements and
associates a value with each element in the parse
stack. For example when lex returns an INTEGER
token yacc shifts this token to the parse stack. At
the same time the corresponding yylval is shifted
to the value stack. The parse and value stacks are
always synchronized so finding a value related to
a token on the stack is easily accomplished.
121- By Jaydeep Patil AISSMS's IOIT Pune
119. • The left-hand side of a production, or nonterminal, is entered left-justified
and followed by a colon. This is followed by the right-hand side of the
production. Actions associated with a rule are entered in braces.
• With left-recursion, we have specified that a program consists of zero or
more expressions. Each expression terminates with a newline. When a
newline is detected we print the value of the expression. When we apply
the rule
• expr: expr '+' expr { $$ = $1 + $3; }
• we replace the right-hand side of the production in the parse stack with
the left-hand side of the same production. In this case we pop “expr '+'
expr” and push “expr”. We have reduced the stack by popping three terms
off the stack and pushing back one term. We may reference positions in
the value stack in our C code by specifying “$1” for the first term on the
right-hand side of the production, “$2” for the second, and so on. “$$”
designates the top of the stack after reduction has taken place. The above
action adds the value associated with two expressions, pops three terms
off the value stack, and pushes back a single sum. As a consequence the
parse and value stacks remain synchronized.
123- By Jaydeep Patil AISSMS's IOIT Pune
120. • Numeric values are initially entered on the stack when we
reduce from INTEGER to expr. After INTEGER is shifted to
the stack we apply the rule
• expr: INTEGER { $$ = $1; }
• The INTEGER token is popped off the parse stack followed
by a push of expr. For the value stack we pop the integer
value off the stack and then push it back on again. In other
words we do nothing. In fact this is the default action and
need not be specified. Finally, when a newline is
encountered, the value associated with expr is printed.
• In the event of syntax errors yacc calls the user-supplied
function yyerror. If you need to modify the interface to
yyerror then alter the canned file that yacc includes to fit
your needs. The last function in our yacc specification is
main. This example still has an ambiguous grammar.
Although yacc will issue shift-reduce warnings it will still
process the grammar using shift as the default operation.
124- By Jaydeep Patil AISSMS's IOIT Pune
121. • The lexical analyzer returns VARIABLE and INTEGER tokens. For variables yylval
specifies an index to the symbol table sym. For this program sym merely holds the
value of the associated variable. When INTEGER tokens are returned, yylval
contains the number scanned.
125- By Jaydeep Patil AISSMS's IOIT Pune
122. • The input specification for yacc follows. The
tokens for INTEGER and VARIABLE are utilized by
yacc to create #defines in y.tab.h for use in lex.
This is followed by definitions for the arithmetic
operators. We may specify %left, for left-
associative or %right for right associative. The last
definition listed has the highest precedence.
Consequently multiplication and division have
higher precedence than addition and subtraction.
All four operators are left-associative. Using this
simple technique we are able to disambiguate
our grammar.
126- By Jaydeep Patil AISSMS's IOIT Pune
124. • extern void *malloc();
• malloc accepts an argument of type size_t,
and size_t may be defined as unsigned long. If
you are passing ints (or even unsigned ints),
malloc may be receiving garbage (or similarly
if you are passing a long but size_t is int).
128- By Jaydeep Patil AISSMS's IOIT Pune
126. Beyond syntax analysis
•An identifier named x has been recognized.
–Is x a scalar, array or function?
–How big is x?
–If x is a function, how many and what type of arguments does it take?
–Is x declared before being used?
–Where can x be stored?
–Is the expression x+y type-consistent?
•Semantic analysis is the phase where we collect information about the types
of expressions and check for type related errors.
•The more information we can collect at compile time, the less overhead we
have at run time.
130- By Jaydeep Patil AISSMS's IOIT Pune
127. Semantic Analysis
•The syntax of a programming language
describes the proper form of its programs,
•while the semantics of the language defines
what its programs mean; that is, what each
program does when it executes.
131- By Jaydeep Patil AISSMS's IOIT Pune
128. Semantic analysis
•Collecting type information may involve "computations"
–What is the type of x+y given the types of x and y?
•Tool: attribute grammars
–Each grammar symbol has a number of associated attributes:
–The type of a variable or expression
–The value of a variable or expression
–The code for a statement
–Etc.
–The grammar is augmented with special equations (called semantic
actions) that specify how the values of attributes are computed from other
attributes.
–The process of using semantic actions to evaluate attributes is called
syntax-directed translation.
132- By Jaydeep Patil AISSMS's IOIT Pune
130. •A compiler must check that the source program
follows both syntactic and semantic conversion of the
source language.
•This checking called static checking (to distinguish it
from dynamic checking during execution of the target
program), ensure that certain kinds of programming
errors will be detected and reported.
134- By Jaydeep Patil AISSMS's IOIT Pune
131. •Example of Static Checks:
–Type Checks : A Compiler Should report error if an operator
applied to an incompatible operand.
–Flow of Control Checks: Statement that cause flow of
control to leave a construct must have some place to which
to transfer the flow of control.
–Uniqueness check: There are some situations in which an
object must be defined only once.
–Name-Related Check: Sometimes the same name must
appear two or more times. Ex. In ADA, A loop or block may
have a name that appears at the beginning and end of the
construct. The compiler must check same name is used at
both places.
135- By Jaydeep Patil AISSMS's IOIT Pune
132. Type Checking
•TYPE CHECKING is the main activity in semantic
analysis.
•Goal: calculate and ensure consistency of the type of
every expression in a program
•If there are type errors, we need to notify the user.
•Otherwise, we need the type information to generate
code that is correct.
136- By Jaydeep Patil AISSMS's IOIT Pune
134. Type systems
•Every language has a set of types and rules for
assigning types to language constructs.
•Example from the C specification:
–“The result of the unary & operator is a pointer to the
object referred to by the operand. If the type of the operand
is ‘…’ then the type of the result is ‘pointer to …’
•Usually, every expression has a type.
•Type have structure: the type ‘pointer to int’ is
•CONSTRUCTED from the type ‘int’
138- By Jaydeep Patil AISSMS's IOIT Pune
135. Basic vs. constructed types
•Most programming languages have basic and
constructed types.
•BASIC TYPES are the atomic types provided by the
language.
–Pascal: boolean, character, integer, real
–C: char, int, float, double
•CONSTRUCTED TYPES are built up from basic types.
–Pascal: arrays, records, sets, pointers
–C: arrays, structs, pointers
139- By Jaydeep Patil AISSMS's IOIT Pune
136. Type expressions
•We denote the type of language constructs with TYPE
EXPRESSIONS.
•Type expressions are built up with TYPE
CONSTRUCTORS.
1.A basic type is a type expression. The basic types are
boolean, char, integer, and real. The special basic type
type_error signifies an error. The special type void
signifies “no type”
2.A type name is a type expression (type names are like
typedefs in C)
140- By Jaydeep Patil AISSMS's IOIT Pune
137. Type expressions
1.A type constructor applied to type expressions is a type expression.
a.Arrays: if T is a type expression, then pointer(T) is a type expression denoting
the type “pointer to an object of type T”
b.Array(I,T) I: index set, T: element type
c.Products: if T1 and T2 are type expressions, then their Cartesian product T1 ×
T2 is also a type expression.
d.Records: a record is a special kind of product in which the fields have names
(examples below)
e.Pointers: if T is a type expression, then pointer(T) is a type expression denoting
the type “pointer to an object of type T”
f.Functions: functions map elements of a domain D to a range R, so we write D ->
R to denote “function mapping objects of type D to objects of type R” (examples
below)
2.Type expressions may contain variables, whose values are themselves type
expressions. polymorphism
141- By Jaydeep Patil AISSMS's IOIT Pune
138. Record type expressions
•The Pascal code
• type row = record
• address: integer;
• lexeme: array[1..15] of char
• end;
• var table: array[1..10] of row;
•associates type expression
•record((address × integer) × (lexeme × array(1..15,char)))
•with the variable row, and the type expression
•array(1..101,record((address × integer) × (lexeme × array(1..15,char)))
•with the variable table
142- By Jaydeep Patil AISSMS's IOIT Pune
139. Function type expressions
•The C declaration
•int *foo( char a, char b );
•would associate type expression
•char × char -> pointer(integer)
•with foo. Some languages (like ML) allow all sorts of
crazy function types, e.g.
• (integer -> integer) -> (integer -> integer)
•denotes functions taking a function as input and
returning another function
143- By Jaydeep Patil AISSMS's IOIT Pune
140. Graph representation of type expressions
•The recursive structure of a type can be represented
with a tree, e.g. for char × char -> pointer(integer):
•Some compilers explicitly use graphs like these to
represent the types of expressions.
144- By Jaydeep Patil AISSMS's IOIT Pune
141. Type systems and checkers
•A TYPE SYSTEM is a set of rules for assigning
type expressions to the parts of a program.
•Every type checker implements some type
system.
•Syntax-directed type checking is a simple
method to implement a type checker.
145- By Jaydeep Patil AISSMS's IOIT Pune
142. Static vs. dynamic type checking
•STATIC type checking is done at compile time.
•DYNAMIC type checking is done at run time.
•Any kind of type checking CAN be done at run time.
•But this reduces run-time efficiency, so we want to do static
checking when possible.
•A SOUND type system is one in which ALL type errors can be
found statically.
•If the compiler guarantees that every program it accepts will run
without type errors, then the language is STRONGLY TYPED.
146- By Jaydeep Patil AISSMS's IOIT Pune
144. Example type checker
•Let’s build a translation scheme to synthesize
the type of every expression from its
subexpressions.
•Here is a Pascal-like grammar for a sequence of
declarations (D) followed by an expression (E)
•Example program: key: integer;
• key mod 1999
P → D ; E
D → D ; D | id : T
T → char | integer | array [ num ] of T | ↑ T
E → literal | num | id | E mod E | E [ E ] | E ↑
148- By Jaydeep Patil AISSMS's IOIT Pune
145. The type system
•The basic types are char and integer.
•type_error signals an error.
•All arrays start at 1, so
•array[256] of char
•leads to type expression: array(1..256,char)
•The symbol ↑ in an declaration specifies a pointer
type,
•so
• ↑ integer
•leads to type expression: pointer(integer)
149- By Jaydeep Patil AISSMS's IOIT Pune
146. Translation scheme for
declarations
•P → D ; E
•D → D ; D
•D → id : T { addtype(id.entry, T.type) }
•T → char { T.type := char }
•T → integer { T.type := integer }
•T → ↑T1 { T.type := pointer(T1.type) }
•T → array [ num ] of T1
• { T.type := array(1 .. num.val, T1.type) }
150- By Jaydeep Patil AISSMS's IOIT Pune
147. Type checking for expressions
•E → literal { E.type := char }
•E → num { E.type := integer }
•E → id { E.type := lookup(id.entry) }
•E → E1 mod E2 { if E1.type =integer and E2.type = integer
• then E.type := integer
• else E.type := type_error }
•E → E1 [ E2 ] { if E2.type = integer and E1.type = array(s,t)
• then E.type := t else E.type := type_error }
•E → E1↑ { if E1.type = pointer(t)
• then E.type := t else E.type := type-error }
Once the identifiers and their types have been inserted into the symbol table, we can
check the type of the elements of an expression:
151- By Jaydeep Patil AISSMS's IOIT Pune
148. How about boolean types?
•Try adding
• T -> boolean
• Relational operators < <= = >= > <>
• Logical connectives and or notto the
grammar, then add appropriate type checking
semantic actions.
152- By Jaydeep Patil AISSMS's IOIT Pune
149. Type checking for statements
•Usually we assign the type VOID to statements.
•If a type error is found during type checking,
though, we should set the type to type_error
•Let’s change our grammar allow statements:
• P → D ; S
•i.e., a program is a sequence of declarations
followed by a sequence of statements.
153- By Jaydeep Patil AISSMS's IOIT Pune
150. Type checking for statements
•S → id := E { if id.type = E.type then S.type := void
• else S.type := type_error }
•S → if E then S1 { if E.type = boolean
• then S.type := S1.type
• else S.type := type_error }
•S → while E do S1 { if E.type = boolean
• then S.type := S1.type
• else S.type := type_error }
•S → S1 ; S2 { if S1.type = void and S2.type = void
• then S.type := void
• else S.type := type_error.
Now we need to add productions and semantic actions:
154- By Jaydeep Patil AISSMS's IOIT Pune
151. Type checking for function calls
•Suppose we add a production E → E ( E )
•Then we need productions for function declarations:
E → E1 ( E2 ) { if E2.type = s and E1.type = s → t
then E.type := t
else E.type := type_error }
T → T1 → T2 { T.type := T1.type → T2.type }
and function calls:
155- By Jaydeep Patil AISSMS's IOIT Pune
152. Type checking for function calls
•Multiple-argument functions, however, can be
modeled as functions that take a single PRODUCT
argument.
• root : ( real → real ) x real → real
•this would model a function that takes a real function
•over the reals, and a real, and returns a real.
•In C:float root( float (*f)(float), float x );
156- By Jaydeep Patil AISSMS's IOIT Pune
153. Type expression equivalence
•Type checkers need to ask questions like:
• – “if E1.type == E2.type, then …”
•What does it mean for two type expressions to be
equal?
•STRUCTURAL EQUIVALENCE says two types are the
same if they are made up of the same basic types and
constructors.
•NAME EQUIVALENCE says two types are the same if
their constituents have the SAME NAMES.
157- By Jaydeep Patil AISSMS's IOIT Pune
154. Structural Equivalence
•boolean sequiv( s, t )
•{
• if s and t are the same basic type
• return TRUE;
• else if s == array( s1, s2 ) and t == array( t1, t2 )
• return sequiv( s1, t1 ) and sequiv( s2, t2 )
• else s == s1 x s2 and t = t1 x t2 then
• return sequiv( s1, t1 ) and sequiv( s2, t2 )
• else if s == pointer( s1 ) and t == pointer( t1 )
• return sequiv( s1, t1 )
• else if s == s1 → s2 and t == t1 → t2 then
• return sequiv( s1, t1 ) and sequiv( s2, t2 )
• return false
•}
158- By Jaydeep Patil AISSMS's IOIT Pune
155. Relaxing structural equivalence
•We don’t always want strict structural equivalence.
•E.g. for arrays, we want to write functions that accept
arrays of any length.
•To accomplish this, we would modify sequiv() to
accept any bounds:
• …
• else if s == array( s1, s2 ) and t == array( t1, t2 )
• return sequiv( s2, t2 )
• …
159- By Jaydeep Patil AISSMS's IOIT Pune
156. Encoding types
•Recursive routines are very slow.
•Recursive type checking routines increase the
compiler’s run time.
•In the compilers of the 1970’s and 1980’s,
compilers took too long time to run.
•So designers came up with ENCODINGS for
types that allowed for faster type checking.
160- By Jaydeep Patil AISSMS's IOIT Pune
157. Name equivalence
•Most languages allow association of names with type expressions. This
makes type equivalence trickier.
•Example from Pascal:
• type link = ↑cell;
• var next: link;
• last: link;
• p: ↑ cell;
• q,r: ↑ cell;
•Do next, last, p, q, and r have the same type?
•In Pascal, it depends on the implementation!
•In structural equivalence, the types would be the same.
•But NAME EQUIVALENCE requires identical NAMES.
161- By Jaydeep Patil AISSMS's IOIT Pune
158. Handling cyclic types
•Suppose we had the Pascal declaration
• type link = ↑cell;
• cell = record
• info: integer;
• next: link;
• end;
•The declaration of cell contains itself (via the next
pointer).
•The graph for this type therefore contains a cycle.
162- By Jaydeep Patil AISSMS's IOIT Pune
159. Cyclic types
•The situation in C is slightly different, since it is
impossible to refer to an undeclared name.
• typedef struct _cell {
• int info;
• struct _cell *next;
• } cell;
• typedef *cell link;
•But the name link is just shorthand for
• (struct _cell *).
•C uses name equivalence for structs to avoid recursion
•(after expanding typedef’s).
•But it uses structural equivalence elsewhere.
163- By Jaydeep Patil AISSMS's IOIT Pune
160. Type conversion
•Suppose we encounter an expression x+i where x has type float and i has
type int. CPU instructions for addition could take EITHER float OR int as
operands, but not a mix.
•This means the compiler must sometimes convert the operands of
arithmetic expressions to ensure that operands are consistent with operators.
•With postfix as an intermediate language for expressions, we could express
the conversion as follows:
x i inttoreal float+
•where real+ is the floating point addition operation.
164- By Jaydeep Patil AISSMS's IOIT Pune
161. Type coercion
•If type conversion is done by the compiler without the
programmer requesting it, it is called IMPLICIT
conversion or type COERCION.
•EXPLICIT conversions are those that the programmer
• specifices, e.g.
• x = (int)y * 2;
•Implicit conversion of CONSTANT expressions should
be done at compile time.
165- By Jaydeep Patil AISSMS's IOIT Pune
162. Type checking example with coercion
•Production Semantic Rule
•E -> num E.type := integer
•E -> num . num E.type := real
•E -> id E.type := lookup( id.entry )
•E -> E1 op E2 E.type := if E1.type == integer and E2.type == integer
• then integer
• else if E1.type == integer and E2.type == real
• then real
• else if E1.type == real and E2.type == integer
• then real
• else if E1.type == real and E2.type == real
• then real
• else type_error
166- By Jaydeep Patil AISSMS's IOIT Pune
163. END of Unit 2
167- By Jaydeep Patil AISSMS's IOIT Pune