0% found this document useful (0 votes)
8 views9 pages

SPCC Prac Implementation

The document outlines the implementation of FIRST and FOLLOW sets for a given grammar, along with code optimizations such as algebraic simplification and common subexpression elimination. It also includes a lexical analyzer that identifies keywords, symbols, and identifiers from source code. Additionally, it demonstrates unreachable code elimination and constant propagation techniques.

Uploaded by

mayankgopal2004
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)
8 views9 pages

SPCC Prac Implementation

The document outlines the implementation of FIRST and FOLLOW sets for a given grammar, along with code optimizations such as algebraic simplification and common subexpression elimination. It also includes a lexical analyzer that identifies keywords, symbols, and identifiers from source code. Additionally, it demonstrates unreachable code elimination and constant propagation techniques.

Uploaded by

mayankgopal2004
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/ 9

FIRST and FOLLOW set:

grammar = {
'S': ['AB'],
'A': ['aA', 'ε'],
'B': ['b']
}

first, follow = {}, {'S': {'$'}}

def get_first(x):
if x not in grammar: return {x}
if x in first: return first[x]
res = set()
for prod in grammar[x]:
if prod == 'ε': res.add('ε')
else:
for ch in prod:
f = get_first(ch)
res |= f - {'ε'}
if 'ε' not in f: break
else: res.add('ε')
first[x] = res
return res

def get_follow():
for nt in grammar: follow.setdefault(nt, set())
changed = True
while changed:
changed = False
for A in grammar:
for prod in grammar[A]:
for i, B in enumerate(prod):
if B not in grammar: continue
beta = prod[i+1:]
temp = set()
for sym in beta:
f = get_first(sym)
temp |= f - {'ε'}
if 'ε' not in f: break
else: temp |= follow[A]
if not temp <= follow[B]:
follow[B] |= temp
changed = True

for nt in grammar: get_first(nt)


get_follow()

for nt in grammar:
print(f"FOLLOW({nt}) = {follow[nt]}")
CODE OPTIMISATION 1:
def algebraic_simplify(expr):
lhs, rhs = expr.split('=')
lhs = lhs.strip()
rhs = rhs.strip()

# Simplify common algebraic patterns


if '+ 0' in rhs or '0 +' in rhs:
rhs = rhs.replace('+ 0', '').replace('0 +', '')
if '* 1' in rhs or '1 *' in rhs:
rhs = rhs.replace('* 1', '').replace('1 *', '')
if '* 0' in rhs or '0 *' in rhs:
rhs = '0'

return f"{lhs} = {rhs.strip()}"

def eliminate_common_subexpr(code):
expr_map = {}
new_code = []
for line in code:
lhs, rhs = line.split('=')
lhs = lhs.strip()
rhs = rhs.strip()
if rhs in expr_map:
new_code.append(f"{lhs} = {expr_map[rhs]}")
else:
expr_map[rhs] = lhs
new_code.append(line)
return new_code

# Input code
code = [
"a = b + c",
"d = b + c",
"e = a + 0",
"f = d * 1",
"g = f * 0"
]

# Apply Algebraic Simplification


code = [algebraic_simplify(line) for line in code]

# Apply Common Subexpression Elimination


code = eliminate_common_subexpr(code)

# Output optimized code


print("Optimized Code:")
for line in code:
print(line)
CODE OPTIMIZATION 2:
def unreachable_code(code):
for i in range(len(code)):
if code[i] == "return":
return code[:i+1]
return code
code = ["x = 1", "return", "y = 2"]
print("Before Unreachable Code Elimination:", code)
print("After Unreachable Code Elimination:",
unreachable_code(code))

def constant_propagation_eval(code, replacements):


for var, value in replacements.items():
code = code.replace(var, str(value))
return eval(code)
# Example usage
code = "PI * 100 * 100"
replacements = {"PI": 3.14} # Replace PI with 3.14
print("Before Constant Propagation:", code)
result = constant_propagation_eval(code, replacements)
print("After Constant Propagation:", result)
LEXICAL ANALYZER 1:
# List of language keywords (you can expand this list)
keywords = {
"if", "else", "while", "for", "return", "int", "float", "char", "void",
"main", "break", "continue"
}

# List of symbols (you can expand this list)


symbols = {
'(', ')', '{', '}', '[', ']', ';', ',', '+', '-', '*', '/', '=', '<', '>', '!', '&', '|'
}

def is_identifier(token):
return token[0].isalpha() or token[0] == '_'

def lexical_analyzer(code):
tokens = []
word = ''

i=0
while i < len(code):
ch = code[i]

# If the character is a symbol


if ch in symbols:
if word:
tokens.append(word)
word = ''
tokens.append(ch)
i += 1

# If whitespace, flush word if exists


elif ch.isspace():
if word:
tokens.append(word)
word = ''
i += 1

# For compound symbols like '==', '!=', '<=', '>='


elif ch in ['<', '>', '=', '!', '&', '|'] and i+1 < len(code) and code[i+1]
== '=':
if word:
tokens.append(word)
word = ''
tokens.append(ch + '=')
i += 2

else:
word += ch
i += 1
if word:
tokens.append(word)

# Classify tokens
for token in tokens:
if token in keywords:
print(f"{token} -> Keyword")
elif token in symbols or token in ['==', '!=', '<=', '>=']:
print(f"{token} -> Symbol")
elif is_identifier(token):
print(f"{token} -> Identifier")
else:
print(f"{token} -> Unknown")

# Example input (you can modify this for testing)


source_code = """
int main() {
int a = 10;
float b = 20.5;
if (a < b) {
return a;
}
}
"""
lexical_analyzer(source_code)

You might also like