0% found this document useful (0 votes)
17 views

1.Backus-Naur Form (BNF) : G= (V,Σ,R,S) Σ

Uploaded by

shaikilyas0579
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)
17 views

1.Backus-Naur Form (BNF) : G= (V,Σ,R,S) Σ

Uploaded by

shaikilyas0579
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/ 20

Formal methods for describing syntax are structured approaches used in

computer science and linguistics to define the rules that govern the structure of
valid sentences or strings in a language. These methods ensure clarity and
unambiguity when defining the syntax of programming languages or formal
languages. Here are the most common formal methods:
1.Backus-Naur Form (BNF)
BNF is a notation for formally specifying context-free grammars. It consists of a set
of production rules that describe how sentences in a language are constructed. In
BNF, syntactic rules are written in terms of terminal and non-terminal symbols.
• Terminal symbols are the actual characters or tokens that appear in the
language (like a, b, 1, +).
• Non-terminal symbols represent syntactic categories (like <expression>,
<term>).
EX:-
<expression> ::= <term> "+" <term> | <term>
<term> ::= <factor> "*" <factor> | <factor>
<factor> ::= "(" <expression> ")" | <number>
<number> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
2.Context-Free Grammar (CFG)
A context-free grammar is a collection of rules used to generate strings of a
language. Each rule specifies how a symbol can be replaced by a combination of
other symbols. CFGs are defined formally as a 4-tuple: G=(V,Σ,R,S)G = (V, \Sigma,
R, S)G=(V,Σ,R,S), where:
• VVV is a set of non-terminal symbols.
• Σ\SigmaΣ is a set of terminal symbols.
• RRR is a set of production rules.
• SSS is the start symbol.
3. Extended Backus-Naur Form (EBNF)
EBNF extends BNF by adding more convenient notation. It allows for specifying
optional elements, repetition, and grouping, making it more compact and
expressive than BNF.
• Optional elements are enclosed in square brackets [].
• Repetitions are denoted using curly braces {}.
• Choices are indicated by the pipe symbol |.
EX:-
expression ::= term { "+" term }
term ::= factor { "*" factor }
factor ::= "(" expression ")" | number
number ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9
4. Grammars
A grammar is a formal system that defines the structure of a language. It
consists of a set of rules that specify how valid strings (sentences) in that
language can be formed. Grammars are used in programming languages,
natural languages, and more. The most common types of grammars include
Recognizers
A recognizer is a computational model that determines whether a given string
belongs to a specific language defined by a grammar. Recognizers can be
implemented in various forms, such as:
a. Deterministic Finite Automaton (DFA)
b. Non-deterministic Finite Automaton (NFA)
c.Pushdown Automaton (PDA)
2nd
When discussing the meaning of programs through the lens of semantics in
programming languages, we can categorize the different semantic approaches
into three main types: operational semantics, denotational semantics, and
axiomatic semantics
When discussing the meaning of programs through the lens of semantics in
programming languages, we can categorize the different semantic approaches
into three main types: operational semantics, denotational semantics, and
axiomatic semantics. Each of these approaches provides a distinct way to
understand how programs behave and how their meanings can be formalized.
Here’s a detailed breakdown of these semantic approaches:
1. Operational Semantics
Operational semantics describes the meaning of a program in terms of the
operations that are performed during its execution. It provides a step-by-step
account of how a program runs on a machine or an abstract model of
computation. This approach focuses on the transitions between states as the
program executes.
• Key Characteristics:
o State: Represents the current configuration of a program, including
the values of variables, control flow, and the environment.
o Transition Rules: Defines how to move from one state to another
based on the execution of program constructs (statements,
expressions).
o Abstract Machines: Often uses abstract machines (like the small-step
or big-step semantics) to describe the execution model of the
language
Example: For a simple arithmetic expression like x = a + b, operational
semantics would define:
1. Read the values of a and b from the current state.
2. Compute the sum.
3. Update the state by binding x to the computed value.
Denotational Semantics
Denotational semantics assigns mathematical objects (denotations) to program
constructs, providing a formal, abstract representation of their meaning. Instead
of describing how a program executes, it describes what a program computes,
often using functions.
• Key Characteristics:
o Mathematical Functions: Each construct of the programming
language is mapped to a mathematical function that represents its
meaning.
o Environment: Denotations may include an environment that maps
variable names to values, capturing the scope and bindings.
o Domain Theory: Often uses domain theory to deal with potentially
infinite structures and recursive definitions.
Axiomatic Semantics
Axiomatic semantics defines the meaning of programs through logical assertions
about their behavior. This approach uses formal logic to specify preconditions and
postconditions for program statements, focusing on what must be true before and
after the execution of a program.
o Proofs: Enables reasoning about program correctness through formal
proofs based on assertions.
• Example: For a simple assignment like x = a + b, the axiomatic semantics
might specify:
o Precondition: P:a is defined and b is definedP: \text{a is defined and b
is defined}P:a is defined and b is defined
o Postcondition: Q:x=a+bQ: x = a + bQ:x=a+b
o We can express this as {P}x=a+b{Q}\{P\} x = a + b \{Q\}{P}x=a+b{Q}.
Variables
In programming languages, variables are symbolic names that reference values
stored in memory. Variables hold data that can be manipulated throughout the
execution of a program. The attributes of variables define their behavior and
characteristics, such as scope, type, mutability, and lifetime. Let’s dive into the
meaning of variables and their key attributes in detail.

Definition of Variables
A variable is a named storage location in a program where data is stored. The
value of a variable can typically be modified during the program's execution unless
the variable is immutable (a constant).
Ex :- x = 10
y = "Hello"
Attributes of Variables
Variables have several important attributes that determine their behavior and
how they interact with data. The most common attributes include:
1. Type
The type of a variable defines the kind of data it can hold. Programming languages
can be either statically typed (where the type is defined at compile time) or
dynamically typed (where the type is determined at runtime).
• Statically Typed Languages: In languages like C, C++, and Java, the type of a
variable must be declared before use.
o Example in C:
int x = 5; // 'x' is an integer variable
char name[] = "Alice"; // 'name' is a string (character array)
2.Scope
Scope refers to the region or block of code where a variable is accessible. The
scope of a variable determines where in the program the variable can be used.
• Local Scope: Variables declared inside a function or block are only
accessible within that function or block.
o Example in Python:
def my_function():
x = 10 # x has local scope and is accessible only within this function
• Global Scope: Variables declared outside all functions or blocks are globally
accessible throughout the program.
Example:
x = 10 # Global variable
def my_function():
print(x) # Accesses the global variable 'x'
3.Lifetime
The lifetime of a variable is the duration for which the variable exists in memory
and can be accessed during the execution of a program.
• Automatic Variables: Variables that are created and destroyed
automatically when their block or function is entered and exited,
respectively (e.g., local variables in most languages).
o Example:
def my_function():
x = 5 # 'x' is created when the function is called and destroyed after it ends
Static Variables: Variables that retain their value even after the function or block
in which they are declared finishes executing
Global Variables: Variables that exist for the entire duration of the program.
4.Variable Naming Conventions
Naming conventions help ensure that variable names are meaningful and improve
code readability. Common practices include:
• Descriptive Names: Use meaningful names that describe the purpose of the
variable (e.g., total_cost, student_name).
• Camel Case: Common in languages like Java (e.g., totalCost).
• Snake Case: Used in languages like Python (e.g., total_cost).
• Hungarian Notation: Prefixing variables with a type indicator (e.g., iCount
for an integer count).

Concept of binding
The concept of binding in programming languages refers to the association of program
elements (such as variables, functions, or types) with specific values, memory locations, or
behaviors. Binding defines the relationship between a name (like a variable or function name)
and an entity (such as a value, memory address, or code) in the program.
In simple terms, when you "bind" a variable, you're associating a variable name with a particular
memory location where its value is stored. Similarly, binding also applies to functions and other
programming constructs.
Types of Binding
Bindings can be classified based on when and how they occur in a program. The two most
common types are static (early) binding and dynamic (late) binding.

Static (Early) Binding


Static binding occurs at compile time (before the program runs). The association
between the name and the value or type is established during compilation and
remains fixed throughout the program's execution.
• Example: In statically typed languages (like C, C++, or Java), variable types
are bound at compile time, meaning the type of the variable and often the
memory address are fixed during compilation.
• Example in C++:
int x = 10; // 'x' is bound to the integer value 10 at compile time
Advantages of Static Binding:
Performance:
Type Safety
Dynamic (Late) Binding
Dynamic binding occurs at runtime (while the program is running). The
association between the name and the entity is resolved during execution rather
than during compilation.
• Example in Python:
x = 10 # At runtime, 'x' is bound to the integer value 10
x = "Hello" # Now, 'x' is rebound to the string "Hello"
Advantages of Dynamic Binding:
• Flexibility.
• Polymorphism

Other Types of Binding


Beyond the distinction between static and dynamic, there are other important
aspects of binding to consider:
1.Name Binding
Name binding refers to the association of identifiers (variable names, function
names, etc.) with entities (like values or functions). When you declare a variable
or a function, you're binding that name to a specific entity in the program's
environment.
2.Address Binding
Address binding refers to the process of associating a variable with a specific
memory location where its value will be stored. This is more common in low-level
languages like C or assembly.
3.Type Binding
Type binding refers to the association of a variable with a specific data type. This
is crucial in statically typed languages where variables must be declared with a
specific type.
• Static Type Binding: The type is bound at compile time (e.g., int x in C).
• Dynamic Type Binding: The type is determined at runtime (e.g., in Python
or JavaScript)

3rd
Primitive Data Types
Primitive data types are predefined by the programming language. They represent
the simplest and most basic types of data. The exact types of primitive data types
can vary slightly between languages, but the common ones include:
Common Primitive Types:
• Numeric Types (Integers, Floating-point numbers)
• Boolean Type (True/False values)
• Character Type (Single characters)
1.Numeric Data Types
Numeric data types represent numbers and are broadly categorized into two
types: Integers and Floating-Point numbers. These types differ in terms of the
kind of number they store (whole numbers vs. fractional numbers) and the
amount of memory they consume.
a. Integer Types
Integer types are used to store whole numbers, i.e., numbers without a fractional
part. They can be positive or negative and differ in size and range based on the
programming language.
Examples of Integer Types:
• int: A common type for storing signed integers (e.g., -1, 0, 10, 1000).
• short, long: Variants that define the range and size of the integers. short
uses less memory, while long stores larger numbers.
b.Floating-Point Types
Floating-point types store numbers that have a fractional or decimal part. They
are used when precision and fractional values are required.
Examples of Floating-Point Types:
• float: Single precision (usually 32-bit, up to ~7 decimal digits of precision).
• double: Double precision (usually 64-bit, up to ~15 decimal digits of
precision).
• long double: Extended precision (depending on system architecture,
greater than 64-bit precision).
float pi = 3.14f; // pi is a float
double e = 2.718281828; // e is a double
2.Boolean Data Type
The boolean data type represents two possible values: true or false. It is used
primarily in decision-making structures such as conditionals and loops.
Boolean in Various Languages:
• In C/C++: The bool type holds true or false (1 or 0 internally).
bool is_valid = true; // is_valid is a boolean holding 'true'
3.Character Data Type
The character data type represents a single character (letter, digit, symbol, etc.). It
is typically stored using an ASCII or Unicode encoding scheme.
Character in Various Languages:
• In C/C++: The char type is used to store a single ASCII character.
char letter = 'A'; // Stores the character 'A'
User-Defined Ordinal Types
In programming, ordinal types are data types where values are arranged in a well-
ordered sequence, meaning each value has a distinct successor and predecessor
(except for the first and last values). User-defined ordinal types extend this
concept by allowing programmers to create their own custom types with specific
values arranged in a defined sequence. Common examples of user-defined ordinal
types include enumerations and subrange types.
1. Enumeration Types (Enums)
An enumeration (enum) is a user-defined ordinal type where the programmer
explicitly specifies a list of named constant values. These values are ordered, and
each value is automatically associated with a unique integer (or index).
Key Characteristics of Enums:
• The values of an enum are distinct, ordered, and constant.
• Enum values are often represented as integers (starting from 0 by default).
• The order of the values matters, making them ordinal (e.g., the first value is
smaller than the second).
Ex
from enum import Enum

class Day(Enum):
Monday = 1
Tuesday = 2
Wednesday = 3
Thursday = 4
Friday = 5
Saturday = 6
Sunday = 7
today = Day.Wednesday
2.Subrange Types
A subrange type is another user-defined ordinal type where a subset of an
existing ordinal type (like integers or characters) is used. Subrange types
restrict the values of a variable to a specified range within an existing type.
Key Characteristics of Subrange Types:
• Subrange types are defined by selecting a continuous range from an ordinal
base type.
• These types ensure that variables can only hold values within a defined
range.
• Typically used to improve safety and clarify code by explicitly limiting the
range of possible values.
Ex
Age = 1..100; // Age can only take values between 1 and 100
var
personAge: Age;
begin
personAge := 25; // This is valid
personAge := 105; // This will cause an error since 105 is out of range
end.
Arrays and Associative Arrays
Both arrays and associative arrays are fundamental data structures used to
store collections of data. They serve different purposes based on how data is
stored and accessed. Below is an explanation of both concepts and how they
differ.
Array
An array is a data structure that holds a fixed-size collection of elements of the
same type. Each element in an array is stored in a contiguous block of memory
and can be accessed using an index or position.
Key Characteristics of Arrays:
• Fixed Size: The size of the array is determined when it is created and cannot
be changed dynamically (though in some languages like Python, lists offer
dynamic resizing).
Homogeneous: All elements in an array must be of the same type (e.g., all
integers, all floats, or all strings).
Associative Array
An associative array (also known as a dictionary, hashmap, or map in some
languages) is a data structure that stores elements in key-value pairs. Unlike
regular arrays, where elements are accessed by numeric indices, associative arrays
allow you to access elements using keys, which can be strings, integers, or other
objects, depending on the language.
Key Characteristics of Associative Arrays:
• Key-Value Pairs: Instead of storing values in indexed positions, associative
arrays associate each value with a unique key.
• Dynamic Size: Most associative arrays can grow dynamically as new key-
value pairs are added.
• Fast Access: Using a hash function, associative arrays can retrieve values
associated with a key very quickly.
Record
A record is a data structure that groups multiple fields (or attributes), each
with a distinct name and type. It is similar to an object or a struct in some
programming languages. Unlike arrays where data is indexed by position,
records use named fields to access data, making them suitable for organizing
complex data where each field can have a different data type.
Key Characteristics of Records:
• Named Fields: Each piece of data in a record is accessed via its field name.
• Heterogeneous: Different fields can have different data types.
• Fixed Structure: The structure (fields) of the record is defined at the time of
its creation

Union
A union is a data structure similar to a record, but with one crucial difference: all
fields in a union share the same memory location, meaning only one field can
hold a value at any given time. Unions are commonly used when a variable might
store values of different types but only one at a time.
Key Characteristics of Unions:
• Memory Sharing: All fields use the same memory location, saving space.
• One Active Field: Only one field can store a value at a time; assigning a
value to one field overwrites the other fields.
• Heterogeneous: Fields can be of different types.
Tuple
A tuple is an ordered, immutable collection of elements, where each element
can have a different type. Tuples are similar to arrays but are immutable,
meaning their elements cannot be changed after creation. Tuples are ideal
when you need to store a fixed sequence of elements that should not change,
and order matters.
Key Characteristics of Tuples:
• Ordered: Elements are stored in a specific order, and that order is
preserved.
• Immutable: Once created, the elements of a tuple cannot be modified.
• Heterogeneous: Elements can have different data types.
4. List
A list is an ordered, dynamic collection of elements. Unlike tuples, lists are
mutable, meaning their elements can be modified after creation. Lists allow you
to store multiple elements of the same or different types, and you can
dynamically add or remove elements from the list.
Key Characteristics of Lists:
• Ordered: Elements have a specific order.
• Mutable: Elements can be changed, added, or remove
4th
Expressions in Programming: Arithmetic, Relational, Logical, Boolean, and Mixed-
Mode
Expressions are the building blocks of most programs. They are combinations of variables,
constants, operators, and functions that are evaluated to produce a value. Different types of
expressions exist depending on the nature of the operations being performed and the type of
data being manipulated.
Let’s explore different types of expressions and their characteristics:
Arithmetic Expressions
An arithmetic expression involves the use of arithmetic operators to perform mathematical
operations on numeric data. These operators typically include addition (+), subtraction (-),
multiplication (*), division (/), and modulus (%).
Key Characteristics:
• Operate on numeric types (integers, floats, etc.).
• Evaluate to a numeric result.
• Can include variables, constants, and function calls.

2. Relational Expressions
A relational expression is used to compare two values and evaluates to a Boolean
result: either True or False. The comparison is done using relational operators
such as:
• == (equal to)
• != (not equal to)
• > (greater than)
• < (less than)
• >= (greater than or equal to)
• <= (less than or equal to)
Key Characteristics:
• Operate on both numeric and non-numeric data types.
• Always return a Boolean result (True or False).

3. Logical Expressions
Logical expressions are used to combine multiple relational or Boolean
expressions and evaluate to a single Boolean value. Logical expressions use logical
operators such as:
• and (logical AND)
• or (logical OR)
• not (logical NOT)
Key Characteristics:
• Combine Boolean values or relational expressions.
• Evaluate to a Boolean result (True or False).
4. Boolean Expressions
A Boolean expression is any expression that evaluates directly to a Boolean
value (True or False). These expressions involve either Boolean literals,
variables, or the result of relational or logical expressions.
Key Characteristics:
• The result of a Boolean expression is always either True or False.
• Often used in conditionals (like if statements) to control program flow.

5. Mixed-Mode Expressions
Mixed-mode expressions involve operands of different data types. For example,
you might perform an operation between an integer and a float. In such cases,
programming languages often perform type conversion (either implicitly or
explicitly) to evaluate the expression.
Key Characteristics:
• Combine operands of different types, such as an integer and a float.
• In most languages, type promotion occurs to ensure the operation can be
performed (e.g., an integer might be promoted to a float).
• Explicit type casting can be used to manually convert data types.

You might also like