0% found this document useful (0 votes)
36 views18 pages

Syntax and Semantics: Programming Language

There are many programming languages because they serve different purposes and audiences. While all languages ultimately produce 1s and 0s understood by computers, they differ in how programmers interact with them. Languages are tools suited to different jobs, like how vehicles are suited to different tasks. Programmers also have personal preferences for languages based on how they like to think and problem solve. Businesses also consider what languages their employees already know. Overall, the variety of languages allows for diverse programs, companies, and careers.

Uploaded by

21d41a0513
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views18 pages

Syntax and Semantics: Programming Language

There are many programming languages because they serve different purposes and audiences. While all languages ultimately produce 1s and 0s understood by computers, they differ in how programmers interact with them. Languages are tools suited to different jobs, like how vehicles are suited to different tasks. Programmers also have personal preferences for languages based on how they like to think and problem solve. Businesses also consider what languages their employees already know. Overall, the variety of languages allows for diverse programs, companies, and careers.

Uploaded by

21d41a0513
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 18

PPL-UNIT -1

SYNTAX AND SEMANTICS


Programming Language:
A programming language is a formal language, which comprises a set of instructions used to
produce various kinds of output. Programming languages are used in computer programming to
create programs that implement specific algorithms.
Thousands of different programming languages have been created, mainly in the computer field,
and many more still are being created every year.
The reasons for why there are so many programming Languages are Evolution, purpose of
languages and personal preference.
Why are there so many programming languages?
Aren’t they all the same?
In a sense, yes. You can create a web site using Ruby, Java, Python, C#, Go or JavaScript. You
can use C or C++ or Haskell or Rust. Or COBOL or Pascal or Perl.
Underlying this fact is that all of these languages serve the same purpose: to turn human thoughts
into the 1’s and 0’s that the computer understands.
At their most foundational level, these languages are all the same. But on the surface – where
humans interact with them – they vary a lot. This is where other concerns come into play.
Different tools for different jobs
Programming languages are tools, and we choose different tools for different jobs. A tractor
trailer and a bicycle and a Tesla are all vehicles – they have wheels and steering and will get you
from point A to point B – but obviously we use them for different things.
Programming languages are similar. Ruby and JavaScript are great for building web sites; Java
and C++ are often used for financial trading; Python and R are the tools of choice for analyzing
statistics.
Languages often make trade-offs in terms of convenience, safety, and speed – much like
vehicles. The trade-off is dictated by the job at hand.
Developers have tastes:
Beyond mere utility, developers choose tools based on personal tastes. A programming language
is a tool for humans to express ideas to computers. While we developers have many things in
common, there is natural variety in the way our minds work.
Because we have many choices of good programming languages, we can select one that “works
the way I think”. Some developers like Ruby’s flexibility, while others prefer Java’s strictness.
Where some languages feel like math, others look like prose.
People first
Beyond utility, and beyond taste, businesses run on people. Often, you will choose a
programming language based on what you, or the people around you, know.
Stack Overflow chose C# mostly because that’s what our founders knew. In turn, it’s what the
founders’ friends and colleagues knew. Which made recruiting easier, and allowed Stack to get
to market more quickly.
Technologies are supported by “ecosystems” – communities and organizations that provide the
tools and assistance that every developer needs. A good ecosystem – Ruby has a great one, for
example – can make the individual developer more successful.
Variety is strength: In summary, we have a variety of programming languages because there is a
variety of jobs to be done and a variety of people who do those jobs. This diversity makes
interesting programs – and interesting companies, and interesting careers – possible.

Principles of Programming Languages - Unit-I Kallam Haranadhareddy Institute of Technology, CSE Dept.,Page 1
Reasons for studying concepts of programming Languages:
 Increased capacity to express ideas.
 Improved ability to choose an appropriate language.
 Increased ability to learn new languages.
 Better understanding of implementation issues (i.e., how language constructs are
implemented)
 Improved use of languages one already "knows"
 To design new language.
Increased capacity to express ideas:

Language influences and limits one's ability to express (and even formulate) ideas, because
people tend to "think in a language". Many CS 1 students, for example, have difficulties because
they don't yet know the programming language well enough to know what it can do.
By knowing about the various abstraction mechanisms available in various languages (e.g.,
recursion, objects, associative arrays, functions as "first-class" entities, etc.), a programmer can
more easily solve problems, even if programming in a language lacking an abstraction relevant
to the solution.
Improved ability to choose an appropriate language:
"If all you know is how to use a hammer, every problem looks like a nail."
All general-purpose programming languages are equivalent (i.e., Turing universal) in terms of
capability, but, depending upon the application, one language may be better suited than another.
Examples: COBOL was designed with business applications in mind, FORTRAN for scientific
applications, C for systems programming, SNOBOL for string processing.
Increased ability to learn new languages:
Given how frequently new programming languages rise in popularity, this is an important skill.
• Better understanding of implementation issues (i.e., how language constructs are
implemented)
Helps in figuring out subtle bugs (e.g., caused by a buffer overrun or aliasing) and in playing
tricks to get you "closer" to the hardware in those instances where it is necessary.
Helps in tweaking a program to make more efficient. E.g., When M.G. said, "Recursion is bad.",
he meant that, in some instances, it is better to use iteration because it can be much faster and use
less memory. (Compare a subprogram that recursively sums the elements of an array to one that
does it using a for or while loop.)
Affect upon language design (i.e., which constructs are included vs. excluded).
E.g., FORTRAN was designed to be fast; IBM 704 had three address registers, so arrays were
limited to be no more than 3-dimensional.
E.g., Why are there separate types for integers and reals?
E.g., Why have "associative arrays" become common as built-in constructs only in recently-
introduced languages? Does it have to do with complexity of implementation?
Improved use of languages one already "knows":
By learning about programming language constructs in general, you may come to understand
(and thus begin making use of) features/constructs in your "favorite" language that you may have
not used before.
To design new language:
If the programmers are expets in different programming languages, they even can implement the
new language based on their expertise on existing language.

Principles of Programming Languages - Unit-I Kallam Haranadhareddy Institute of Technology, CSE Dept.,Page 2
Programming Paradigm:
Programming Paradigm is way or style of Programming.
There are different programming paradigms:
1. Imperative paradigm
2. Functional paradigm
3. Logic paradigm
4. Object Oriented paradigm

Imperative paradigm: The language provides statements, such as assignment statements ,


which explicitly change the state of the memory of the computer. The basic means of
computation is the modification of variables.
Example Languages: C,C++, Java, Python, FORTRAN, COBOL
Functional paradigm: In this paradigm we express computations as the evaluation of
mathematical functions. These Languages takes the inspiration of LAMBA calculus. The view of
the program is in the form of function from input to output.
Example Languages:LISP, SCHEME, ML(Meta Language), HASKELL
Logic paradigm: In this paradigm we express computation in exclusively in terms
of mathematical logic that follows the predicate Logic. The computation is based on the result of
the condition ‘true’ or ‘false’.
Example Languages: PROLOG
Object-Oriented Paradigm: In this paradigm we associate behavior(Functions) with data-
structures called " objects " which belong to classes which are usually structured into a
hierarchy.
The paradigms are not exclusive, but reflect the different emphasis of language designers. Most
practical imperative, functional and object-oriented languages embody features of more than one
paradigm.
Example Languages: Java, C++
Language Evaluation Criteria:
Evaluation criteria and several characteristics of programming languages that should be
considered when evaluating a language with respect to those criteria.
The following are evaluation criterias:
Readability Writability Reliability Cost
The following table shows different language evaluation criteria and characters that effect the
criterias.

Criteria
Characteristics Readability Writability Reliability
Simplicity and Orthogonality * * *
Control Statement * * *
Data types and structures * * *
Syntax design * * *
Abstraction * *
Expressivity * *
Type checking *
Exception Handling *
Aliasing *

Principles of Programming Languages - Unit-I Kallam Haranadhareddy Institute of Technology, CSE Dept.,Page 3
Readability: This refers to the ease with which programs can be understood. This is especially
important for software maintenance.
 Simplicity:
o number of basic constructs/features: if there are too many, the more likely a
program will be hard to read (because reader might know a different subset of
language than programmer).
If there are very few (e.g., assembly language), code can be hard to read because
what may be a single operation, conceptually, could require several instructions to
encode it.
o feature multiplicity: the existence of multiple ways of doing the same operation.
Examples: incrementing a variable in C-based syntax, looping constructs (while,
do while, for), Java's conditional ternary operator (?:).
o operator overloading: can aid readability if used with discretion, but can lessen
readability if used unwisely (e.g., by using + as a comparison operator).
 Orthogonality: In the context of a programming language, a set of features/constructs is
said to be orthogonal if those features can be used freely in combination with each other.
In particular, the degree of orthogonality is lessened if
o particular combinations are forbidden (as exceptional cases) or
o the meaning of a particular combination is not evident from the meanings of its
component parts, each one considered without regard to context.
Examples of non-orthogonality in C:
o A function can return a value of any type, except for an array type or a function
type.
o According to Sebesta, an array can hold values of any type, except for a function
type or void. (Note that material on the WWW indicates that you can place
pointers to functions in an array!)
o Parameters to functions are passed "by value", except for arrays, which are, in
effect, passed "by reference". (Is this a valid criticism? After all, one should
understand a variable of an array type to have a value that is actually a pointer to
an array. So passing an array to a function is really passing a pointer "by value".
This is exactly how Java works when passing objects to methods. What is being
passed is really a reference (i.e., pointer) to an object, not the object itself.)
o In the expression a + b, the meaning of b depends upon whether or not a is of a
pointer type. (This is an example of context dependence.)
 Data Types:
Adequate facilities for defining data types and structures aids readability. E.g. Early
FORTRAN had no record/struct construct, so the "fields" of an "object" could not be
encapsulated within a single structure (that could be referred to by one name).
Primitive/intrinsic data types should be adequate, too. E.g., Early versions of C had no
boolean type, forcing programmer to use an int to represent true/false (0 is false,
everything else is true, so flag = 1; would be used to set flag to true.) How about
this statement fragment:
if (k = 5) { ... } else { ... }
 Syntax Design:
o Identifier forms: Should not be too restrictive on length, such as were
FORTRAN 77 and BASIC. In COBOL, identifiers could include dashes, which
can be confused with the subtraction operator.
o Special words: Words such as while, if, end, class, etc., have special meaning
within a program. Are such words reserved for these purposes, or can they be
used as names of variables or subprograms, too?
Principles of Programming Languages - Unit-I Kallam Haranadhareddy Institute of Technology, CSE Dept.,Page 4
The manner in which the beginning/end of a compound statement (e.g., loop) is
signaled can aid or hurt readability. E.g., curly braces vs. end loop.

Writability: This is a measure of how easily a language can be used to develop programs for a
chosen problem domain.
 Simplicity and Orthogonality: Sebesta favors a relatively small number of primitive
constructs (simplicity) and a consistent set of rules for combining them (orthogonality).
(Sounds more like a description of "learnability" than of "writability".)
 Support for Abstraction: This allows the programmer to define and use complicated
structures/operations in ways that allow implementation details to be ignored. This is a
key concept in modern language design.
Data abstraction and process (or procedural) abstraction.
 Expressivity: This is enhanced by the presence of powerful operators that make it
possible to accomplish a lot in a few lines of code. The classic example is APL, which
includes so many operators (including ones that apply to matrices) that it is based upon
an enlarged character set. (There are special keyboards for APL!)
Typically, assembly/machine languages lack expressivity in that each operation does
something relatively simple, which is why a single instruction in a high-level language
could translate into several instructions in assembly language.
Functional languages tend to be very expressive, in part because functions are "first-
class" entities. In Lisp, you can even construct a function and execute it!
Reliability: This is the property of performing to specifications under all conditions.
 Type Checking: This refers to testing for type errors, either during compilation or
execution. The former is preferable, not only because the latter is expensive in terms of
running time, but also because the earlier such errors are found, the less expensive it is to
make repairs.
In Java, for example, type checking during compilation is so tight that just about the only
type errors that will occur during run-time result from explicit type casting by the
programmer (e.g., when casting a reference to an object of class A into one of subclass B
in a situation where that is not warranted) or from an input being of the wrong type/form.
As an example of a lack of reliability, consider earlier versions of C, in which the
compiler made no attempt to ensure that the arguments being passed to a function were of
the right types! (Of course, this is a useful trick to play in some cases.)
 Aliasing: This refers to having two or more (distinct) names that refer to the same
memory cell. This is a dangerous thing. (Also hurts readability/transparency.)
 Readability and Writability: Both have an influence upon reliability in the sense that
programmers are more likely to produce reliable programs when using a language having
these properties.
Cost: The following contribute to the cost of using a particular language:
 Training programmers: cost is a function of simplicity of language
 Writing and maintaining programs: cost is a function of readability and writability.
 Compiling programs: for very large systems, this can take a significant amount of time.
 Executing programs: Having to do type checking and/or index-boundary checking at run-
time is expensive. There is a tradeoff between this item and the previous one
(compilation cost), because optimizing compilers take more time to work but yield
programs that run more quickly.
 Language Implementation System: e.g., Java is free, Ada not
 Lack of reliability: software failure could be expensive (e.g., loss of business, liability
issues)

Principles of Programming Languages - Unit-I Kallam Haranadhareddy Institute of Technology, CSE Dept.,Page 5
Application Domain/Programming Domain:

Application domains
Scientic applications
-typically require simple data structures but a large number of floating-point operations
- typical data structures: arrays and matrices;
typical control constructs: selection and loop
earliest high-level language: FORTRAN
other language: ALGOL 60
Business applications
- requires preparation of detailed, complex reports and precise ways of handling decimal
numbers and character data
- most popular language: COBOL
Systems programming applications
- systems software is used almost continuously and so a language for systems programming must
have fast execution.
- a language used for systems programming must have low-level featurs to access external
devices.
- popular language: C (almost the whole of UNIX is written in C)
Articial intelligence applications
- requires symbolic rather than numeric processing
- typical data structure: linked list
- popular languages: LISP, PROLOG
Programming Environment:

Programming environment is the collection of tools used in the development of software. The
following are different tools in the programming environment:
Text editor
Compiler
Interpreter
Debugger
Linker
Loader

Example of Programming Environments:


Unix is the oldest programming environment which contains different tools for developing the
software. The user separately use these tools
UNIX CDE(Common Desktop Environment) is a GUI(Graphical User Interface) contains
different tools graphically for developing the programs
Turbo C IDE: IDE means Integrated Development Environment which includes all tools for
executing the program. It contains text editor, comiler, linker, loader)
Microsoft Visual Studio.Net: It is a large and elaborate collection of software development tools,
are using in Windows Operating System environment for developing the software. This is useful
to execute .net, Visual Basic, C++, C#, J Script programs

Principles of Programming Languages - Unit-I Kallam Haranadhareddy Institute of Technology, CSE Dept.,Page 6
Differentiate between Hybrid Interpretation and Pure Interpretation?
Compilation:
Programs translated into machine language code that is directly executable
Pure Interpretation:
Programs are interpreted by an "interpreter". Intermediate machine code is not produced.
Hybrid Implementation Systems:
A compromise between compilers and pure interpreters

Comparison of Interpreter and Compiler?

Interpreter Compiler

Scans the entire program and translates it as a whole


Translates program one statement at a time.
into machine code.

It takes large amount of time to analyze the source


It takes less amount of time to analyze the source
code but the overall execution time is comparatively
code but the overall execution time is slower.
faster.

No intermediate object code is generated, hence are Generates intermediate object code which further
memory efficient. requires linking, hence requires more memory.

Continues translating the program until the first error It generates the error message only after scanning the
is met, in which case it stops. Hence debugging is whole program. Hence debugging is comparatively
easy. hard.

Programming language like BASIC, Python, Ruby


Programming language like C, C++ use compilers.
use interpreters.

Briefly write about Virtual Machines?


A virtual machine (VM) is an operating system (OS) or application environment that is installed
on software, which imitates dedicated hardware.
The end user has the same experience on a virtual machine as they would have on dedicated
hardware.
List and explain different phases of compilation process?
The Compiler is useful to translate the high level source program into an equivalent target
program typically in machine language.
The compilation process is a sequence of various phases. Each phase takes input from its
previous stage, has its own representation of source program, and feeds its output to the next
phase of the compiler. Let us understand the phases of a compiler.
The following figure shows different phases of compilation:

Principles of Programming Languages - Unit-I Kallam Haranadhareddy Institute of Technology, CSE Dept.,Page 7
1. Lexical Analyzer
2. Syntax Analyzer
3. Semantic Analyzer
4. Intermediate code generator
5. Code optimizer
6. Target Generator
7. Machine Dependent code optimizer
1. Lexical Analyzer – It reads the program and converts it into tokens. It converts a stream
of lexemes into a stream of tokens. Tokens are defined by regular expressions which are
understood by the lexical analyzer. It also removes white-spaces and comments.
This phase is also called as Scanner.
Example:
x = y + 10
Tokens
X Identifier

= Assignment operator

Y Identifier

+ Addition operator

10 Number

Principles of Programming Languages - Unit-I Kallam Haranadhareddy Institute of Technology, CSE Dept.,Page 8
2. Syntax Analyzer – It is sometimes called as parser. It constructs the parse tree. It takes
all the tokens one by one and uses Context Free Grammar to construct the parse tree.
Here, is a list of tasks performed in this phase:
• Obtain tokens from the lexical analyzer
• Checks if the expression is syntactically correct or not
• Report all syntax errors
• Construct a hierarchical structure which is known as a parse tree
Consider parse tree for the following example
(a+b)*c

3. Semantic Analyzer – It verifies the parse tree, whether it’s meaningful or not. It
furthermore produces a verified parse tree.
 Semantic Analyzer will check for Type mismatches, incompatible operands, a
function called with improper arguments, an undeclared variable, etc.
Example
float x = 20.2;
float y = x*30;
In the above code, the semantic analyzer will typecast the integer 30 to float
30.0 before multiplication

4. Intermediate Code Generator – It generates intermediate code, that is a form which can
be readily executed by machine We have many popular intermediate codes. Example –
Three address code etc. Intermediate code is converted to machine language using the
last two phases which are platform dependent.
Till intermediate code, it is same for every compiler out there, but after that, it depends on
the platform. To build a new compiler we don’t need to build it from scratch. We can take
the intermediate code from the already existing compiler and build the last two parts.
For example,
total = count + rate * 5
Intermediate code with the help of address code method is:

t1 := int_to_float(5)
t2 := rate * t1
t3 := count + t2
total := t3

Principles of Programming Languages - Unit-I Kallam Haranadhareddy Institute of Technology, CSE Dept.,Page 9
5. Code Optimizer – It transforms the code so that it consumes fewer resources and
produces more speed. The meaning of the code being transformed is not altered.
Optimization can be categorized into two types: machine dependent and machine
independent.
This phase removes unnecessary code line and arranges the sequence of
statements to speed up the execution of the program without wasting resources

Example:

Consider the following code

a = intofloat(10)
b=c*a
d=e+b
f= d
Can become
b =c * 10.0
f = e+b

6. Target Code Generator – The main purpose of Target Code generator is to write a code
that the machine can understand. The output is dependent on the type of assembler.
This is the final stage of compilation..
Example:
a = b + 60.0

Would be possibly translated to registers.


MOVF a, R1
MULF #60.0, R2
ADDF R1, R2

7. Machine Dependent Optimization – Machine-dependent optimization is done after the


target code has been generated and when the code is transformed according to the
target machine architecture. It involves CPU registers and may have absolute memory
references rather than relative references.

Describing Syntax and Semantics


Unlike natural languages, computer languages must be clear. The syntax and semantics of
languages must be specified without ambiguity.
The language implementers use the following formal syntax notations for describing Syntax and
Semantics:
Regular Expression
Context Free Grammar
Contex Free Grammar(CFG):

A context-free grammar (CFG) is a set of rules (or productions) used to generate patterns of
strings.

Principles of Programming Languages - Unit-I Kallam Haranadhareddy Institute of Technology, CSE Dept.,Page 10
A Context Free Grammar shows us how to generate a valid string of terminals: begin with the
start symbol. Context free grammar and Regular expressions are same, additionally CFG allows
nested constructs.

Regular Expressions is pattern or an expression that specifies set of strings (tokens). It is any
one of a character, an empty string, an empty set, concatenation of two regular expressions,
alternation or Kleen star.
Examples: 1. “abc”
2. Let r=“ab” and s=“cd” then concatenation of r and s is
rs= “abcd”
3. Alternation means ‘or’. a|b means either ‘a’ or ‘b’
4. Kleen star means that any character with kleen star can be zero or one or more
times will repeats. a* means { , “a”, “aa”, “aaa”, ….}
A CFG consists of the following components:
 A set of terminal symbols, which are the characters of the alphabet that appear in the
strings generated by the grammar.
 A set of nonterminal symbols, which are placeholders for patterns of terminal symbols
that can be generated by the nonterminal symbols.
 A set of productions, which are rules for replacing (or rewriting) nonterminal symbols
(on the left side of the production) in a string with other nonterminal or terminal
symbols (on the right side of the production).
 A start symbol, which is a special nonterminal symbol that appears in the initial string
generated by the grammar.
Example: The following is CFG for an arithmetic expression
Exp  id | number | -exp | (exp) | exp op exp
Op  + | - | * | /
Here the word exp is used at left and right hand side of the first rule.
 The  symbol can be read as “can have the form of” or “goes to”
 The each line in the above grammar is called as rule or production.
 The symbol at left hand side is called non-terminal.
 The symbols which are used to form the string are known as ‘terminal’.
Example: the string a + b contains the terminal a, + and b.
 Terminals cannot appear at left hand side
 Terminals of CFG are called tokens.
 A non-terminal can have one or more productions.
 The ‘non-terminal’ usually at left hand side of the first production rule in the CFG is
called start symbol.
 CFG is sometimes called as BNF(Backus-Naur Form). We use additionally kleen Plus( also
called kleen cross) which indicates the character with kleen Plus can repeat one
or more times. Example: a+ means { a, aa, aaa, …}
Derivation and parse tree:
 Grammar: A set of production rules that describe all possible strings in a given formal
language
 Derivation: A series of replacement operations that shows how to derive the string from
start symbol is called “derivation”. Each symbol along he way of derivation is called
“sentential form”.

Principles of Programming Languages - Unit-I Kallam Haranadhareddy Institute of Technology, CSE Dept.,Page 11
 Derivation process :
1. Begin with a string consisting of the start symbol;
2. Apply one of the productions with the start symbol on the left hand size, replacing the
start symbol with the right hand side of the production;
3. Repeat the process of selecting nonterminal symbols in the string, and replacing them
with the right hand side of some corresponding production, until all nonterminals have
been replaced by terminal symbols.
Example: Derive the expression “slope * x + intercept” using the above CFG of arithmetic
expression.
exp exp or exp
 exp op id
 exp + id
 exp op exp + id
 exp op id + id
 exp * id + id
 id * id + id
 Slope * x + intercept
Derivations are right to left( replace the right most non terminal with its associated
production) or left to right (replace the left most non terminal with its associated
production).
 Parse tree: If we represent the derivation graphically then it is called parse tree.
The root of the parse tree is the start symbol; the leaves of the tree are terminals.\
Example the following is the parse tree for the above derivation:

Ambiguity: Sometimes we will get two or more parse trees for the same string. This is called
ambiguity. We need to avoid the ambiguity with efficient grammars.
Precedence and Associativity:
Precedence means every operator has a priority.
Example * and / operators have more priority than + or – operators.
Associativity”
If the expression has equal priority operators then they should be evaluate from left to right
or right to left. This is called Associativity.
The Precedence and Associativity cab be decided by the Context Free Grammars.
Example: The following is an efficient CFG for an arithmetic expression which avoids ambiguity
and follows the Precedence and Associativity.
exp  term | exp add_op term
term  factor | term mult_op factor
factor  id | number | - factor | (exp)

Principles of Programming Languages - Unit-I Kallam Haranadhareddy Institute of Technology, CSE Dept.,Page 12
add_op  + | -
mult_op  * | /
Derive the string 3 + 4 * 5 using the above CFG.
exp  exp add_op term
 term add_op term
 factor add_op term
 3 add_op term
 3 + term
 3 + term mult_op factor
 3 + factor mult_op factor
 3 + 4 mult_op factor
 3 + 4 * factor
 3+ 4 *5

The following is the parse tree for the above derivation:

The above tree show that ‘*’ operator has more priority than ‘+’ operator

Types of Contex Free Grammars:


Contex Free Grammar is of two types:
1. LL Grammar
2. LR Grammar
LL Grammar: LL grammar is the left to right, Left most derivation
The parser which uses LL grammar is called LL parser or top-to-down or Predictive parser.
LL parser construct a tree from the root, predicting at each step which production will be used
to expand the current node, based on the next available token of input string.
Example: construct the parse tree for the string a, b, c ; using the following id-list grammar:
id-list  id id-list-tail
id-list-tail  , id id-list-tail
id-list-tail  ;

Principles of Programming Languages - Unit-I Kallam Haranadhareddy Institute of Technology, CSE Dept.,Page 13
LR Grammar: LR grammar is the left to right, Right most derivation. This is also called as
bottom-up or shift reduce parser.
It construct a parse tree from the leaves-ip, recognizing a collection of leaves or other nodes
can be joined together as the children of a single parent.
Example construct the parse tree for the string a,b,c; using LR parser:
1)Read the all character one by one:

2)

3)

4)

5)

Principles of Programming Languages - Unit-I Kallam Haranadhareddy Institute of Technology, CSE Dept.,Page 14
Write BNF notation for if-else statements?

A BNF description, or grammar, is a collection of rules. Non-terminal symbols can have two or
more distinct definitions, representing two or more possible syntactic forms in the language.
Multiple definitions can be written as a single rule, with the different definitions separated by
the symbol |, meaning logical OR. For example, a if statement can be described with the rules

In these rules, <stmt> represents either a single statement or a compound statement.

Explain Left Recursion?:


A grammar is left-recursive if and only if there exists a nonterminal symbol {\displaystyle A}A
that can derive to a sentential form with itself as the leftmost symbol. Symbolically,

Principles of Programming Languages - Unit-I Kallam Haranadhareddy Institute of Technology, CSE Dept.,Page 15
What are the limitations of recursive descent parser?
Recursive descent is a simple parsing algorithm that is very easy to implement. It is a top-down
parsing algorithm because it builds the parse tree from the top (the start symbol) down.
The main limitation of recursive descent parsing (and all top-down parsing algorithms in
general) is that they only work on grammars with certain properties. For example, if a grammar
contains any left recursion, recursive descent parsing doesn't work.
Attribute Grammar
Attribute Grammar is the generalization of Contex-Free-Grammar.
In it each grammar symbol is associated with an attribute
The rules defining with attribute values
Semantic analysis and code generation can be described in terms of Annotation or decoration of a parse
tree. Attribute grammar provide the formal frame work for decorating parse tree.
Values are computed from constants and other attributes.
Set of attributes consists of two types attributes:
Synthesized attribute (values are computed from children nodes(bottom-up) ). These are used to pass
semantic information up a parse tree.
Inherited Attribute (values are computed from siblings and parents(to-down)). These are used to pass
semantic information down a tree.
Example: The following is the Context Free grammar and its equivalent Attribute grammar for an
arithmetic expression:
CFG for Arithmetic expression:
E E+T
E E–T
E T
T T*F
T T/F
T F
F  -F
F  (E)
F  Const
Attribubte Grammar for Arithmetic expression:
1. E1  E2 + T
E1.val = sum(E2.val, T.val)
2. E  E – T
E1.val = sub(E2.val, T.val)
3. E  T
E.val = T.val
4. T  T * F
T1.val=Multiply(T2.val, F.val)
5. T  T / F
T1.val=Division(T2.val, F.val)
6. T  F
T.val = F.val
7. F  -F
F1.val= negative(F2.val)
8. F  (E)
F.val=E.val
9. F  Const
F.val=Const.val

Principles of Programming Languages - Unit-I Kallam Haranadhareddy Institute of Technology, CSE Dept.,Page 16
Attribute grammar serves to define the semantics of the program. The rules of the attribute
grammar comes in two forms:
Copy rule: The productions in 3,6,8 and 9 are called copy rules that are specifying one
attribute value is copied to another attribute
Semantic Function: These are associated with grammar rules. They are used to specify how
attribute values are computed.
Computing Attribute Values:
The process of computing the attributes is called Decoration or Annotation of the parse tree.
Synthesized Attribute:
An attribute that gets values from its children. Each symbol in the attribute grammar has almost one
attribute. Attributes of LHS are computed from attributes of RHS.
Example: The following is the parse tree for an expression 4 + 5 * 3 -2

The following is an equivalent attribute grammar parse tree:

Principles of Programming Languages - Unit-I Kallam Haranadhareddy Institute of Technology, CSE Dept.,Page 17
The value attributes are shown in the boxes.
Arrow lines show the attribute flow.
Once the decomposition is complete, the value of the overall expression can be found in the value
attribute of the root in the tree.
In the computation, if the value calculated for the attributes appear on the LHS of the productions are
called synthesized attributes.These values calculated form bottom-up.
Inherited Attribute:
If the value calculated for the attributes appear on the RHS of the productions are called inherited
attributes. The inherited attribute can have one or more attributes.
They allow computing the values from the parent or siblings.
Example: consider the following LL grammar for the subtraction operation.
Exp  const Exp-tail
Exp-tail  - const Exp-tail
Exp-tail  

1. First we pass th 9 into topmost Exp-tail node,


2. Then 9 can be combined with 4
3. The resulting 5 can then pass into the middle Exp-tail node
4. 5 can be combined with 3 to make 2
5. Pass the result upward to the root
Explain L-Attribute and S-attribute Grammars?

Principles of Programming Languages - Unit-I Kallam Haranadhareddy Institute of Technology, CSE Dept.,Page 18

You might also like