0% found this document useful (0 votes)
40 views13 pages

Cdlab 6

The document outlines the implementation of an SLR(1) parsing table and an XML parser using Lex and Yacc. It details the steps for constructing the SLR(1) parsing table, including grammar augmentation, closure computation, and conflict resolution, along with the associated code. Additionally, it describes the XML parser's structure, including Lex rules for tokenization and Yacc rules for validating XML syntax.

Uploaded by

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

Cdlab 6

The document outlines the implementation of an SLR(1) parsing table and an XML parser using Lex and Yacc. It details the steps for constructing the SLR(1) parsing table, including grammar augmentation, closure computation, and conflict resolution, along with the associated code. Additionally, it describes the XML parser's structure, including Lex rules for tokenization and Yacc rules for validating XML syntax.

Uploaded by

yeruvamokshitha
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Roll No:160122733163.. [Link] Date:24-02-2025………...

[Link]: Write a program to implement SLR parsing table

Description: SLR(1) (Simple LR) parsing is a bottom-up parsing technique used in compiler
design to analyze the syntax of programming languages. It is based on LR(0) parsing with an
additional lookahead mechanism provided by FOLLOW sets. The SLR(1) parsing table is
used by the SLR parser to decide the next action based on the current state and the next input
symbol.
The parsing table consists of two main components:
1. Action Table:
o Specifies whether to Shift, Reduce, Accept, or Report an Error based on the
current state and input symbol.
o Shift (S) moves to the next state, while Reduce (R) applies a production rule.
2. Goto Table:
o Defines state transitions when a non-terminal is encountered.
o Helps in reducing the input string to the start symbol.

Algorithm:

 Grammar Augmentation: Add a new start symbol to the grammar.


 Compute Closure: Generate the closure set for the initial state.
 Compute GOTO: Determine the transitions between states based on symbols.
 Generate States: Use closure and GOTO functions to generate all parser states.
 Compute FIRST Sets: Find the FIRST sets of each non-terminal.
 Compute FOLLOW Sets: Determine FOLLOW sets using FIRST sets and rules.
 Build Action Table: Populate shift (S), reduce (R), and accept states in the table.
 Build GOTO Table: Define transitions for non-terminals using state mappings.
 Resolve Conflicts: Handle reduce-reduce and shift-reduce conflicts.
 Print Table: Display the final SLR(1) parsing table.

Code:
import copy

def grammarAugmentation(rules, nonterm_userdef,start_symbol):


newRules = []
newChar = start_symbol + "'"
while (newChar in nonterm_userdef):
newChar += "'"
[Link]([newChar,['.', start_symbol]])
for rule in rules:
k = [Link]("->")
lhs = k[0].strip()
rhs = k[1].strip()
multirhs = [Link]('|')
for rhs1 in multirhs:
rhs1 = [Link]().split()
[Link](0, '.')

Page No. ………………….. Signature of the Faculty………………………...


Roll No:160122733163.. [Link] Date:24-02-2025………...

[Link]([lhs, rhs1])
return newRules

def findClosure(input_state, dotSymbol):


global start_symbol, \
separatedRulesList, \
statesDict
closureSet = []
if dotSymbol == start_symbol:
for rule in separatedRulesList:
if rule[0] == dotSymbol:
[Link](rule)
else:
closureSet = input_state
prevLen = -1
while prevLen != len(closureSet):
prevLen = len(closureSet)
tempClosureSet = []
for rule in closureSet:
indexOfDot = rule[1].index('.')
if rule[1][-1] != '.':
dotPointsHere = rule[1][indexOfDot + 1]
for in_rule in separatedRulesList:
if dotPointsHere == in_rule[0] and in_rule not in
tempClosureSet:
[Link](in_rule)
for rule in tempClosureSet:
if rule not in closureSet:
[Link](rule)
return closureSet

def compute_GOTO(state):
global statesDict, stateCount
generateStatesFor = []
for rule in statesDict[state]:
if rule[1][-1] != '.':
indexOfDot = rule[1].index('.')
dotPointsHere = rule[1][indexOfDot + 1]
if dotPointsHere not in generateStatesFor:
[Link](dotPointsHere)
if len(generateStatesFor) != 0:
for symbol in generateStatesFor:
GOTO(state, symbol)
return

def GOTO(state, charNextToDot):


global statesDict, stateCount, stateMap

Page No. ………………….. Signature of the Faculty………………………...


Roll No:160122733163.. [Link] Date:24-02-2025………...

newState = []
for rule in statesDict[state]:
indexOfDot = rule[1].index('.')
if rule[1][-1] != '.':
if rule[1][indexOfDot + 1] == charNextToDot:
shiftedRule = [Link](rule)
shiftedRule[1][indexOfDot] = shiftedRule[1][indexOfDot + 1]
shiftedRule[1][indexOfDot + 1] = '.'
[Link](shiftedRule)

addClosureRules = []
for rule in newState:
indexDot = rule[1].index('.')
if rule[1][-1] != '.':
closureRes = \
findClosure(newState, rule[1][indexDot + 1])
for rule in closureRes:
if rule not in addClosureRules \
and rule not in newState:
[Link](rule)

for rule in addClosureRules:


[Link](rule)

stateExists = -1
for state_num in statesDict:
if statesDict[state_num] == newState:
stateExists = state_num
break
if stateExists == -1:
stateCount += 1
statesDict[stateCount] = newState
stateMap[(state, charNextToDot)] = stateCount
else:
stateMap[(state, charNextToDot)] = stateExists
return

def generateStates(statesDict):
prev_len = -1
called_GOTO_on = []
while (len(statesDict) != prev_len):
prev_len = len(statesDict)
keys = list([Link]())
for key in keys:
if key not in called_GOTO_on:
called_GOTO_on.append(key)
compute_GOTO(key)
return

Page No. ………………….. Signature of the Faculty………………………...


Roll No:160122733163.. [Link] Date:24-02-2025………...

def first(rule):
global rules, nonterm_userdef, \
term_userdef, diction, firsts
if len(rule) != 0 and (rule is not None):
if rule[0] in term_userdef:
return rule[0]
elif rule[0] == '#':
return '#'
if len(rule) != 0:
if rule[0] in list([Link]()):
fres = []
rhs_rules = diction[rule[0]]
for itr in rhs_rules:
indivRes = first(itr)
if type(indivRes) is list:
for i in indivRes:
[Link](i)
else:
[Link](indivRes)
if '#' not in fres:
return fres
else:
newList = []
[Link]('#')
if len(rule) > 1:
ansNew = first(rule[1:])
if ansNew != None:
if type(ansNew) is list:
newList = fres + ansNew
else:
newList = fres + [ansNew]
else:
newList = fres
return newList
[Link]('#')
return fres
def follow(nt):
global start_symbol, rules, nonterm_userdef, \
term_userdef, diction, firsts, follows
solset = set()
if nt == start_symbol:
[Link]('$')
for curNT in diction:
rhs = diction[curNT]
for subrule in rhs:
if nt in subrule:
while nt in subrule:
index_nt = [Link](nt)
subrule = subrule[index_nt + 1:]

Page No. ………………….. Signature of the Faculty………………………...


Roll No:160122733163.. [Link] Date:24-02-2025………...

if len(subrule) != 0:
res = first(subrule)
if '#' in res:
newList = []
[Link]('#')
ansNew = follow(curNT)
if ansNew != None:
if type(ansNew) is list:
newList = res + ansNew
else:
newList = res + [ansNew]
else:
newList = res
res = newList
else:
if nt != curNT:
res = follow(curNT)
if res is not None:
if type(res) is list:
for g in res:
[Link](g)
else:
[Link](res)
return list(solset)

def createParseTable(statesDict, stateMap, T, NT):


global separatedRulesList, diction
rows = list([Link]())
cols = T+['$']+NT
Table = []
tempRow = []
for y in range(len(cols)):
[Link]('')
for x in range(len(rows)):
[Link]([Link](tempRow))
for entry in stateMap:
state = entry[0]
symbol = entry[1]

a = [Link](state)
b = [Link](symbol)
if symbol in NT:
Table[a][b] = Table[a][b] + f"{stateMap[entry]} "
elif symbol in T:
Table[a][b] = Table[a][b] + f"S{stateMap[entry]} "
numbered = {}
key_count = 0
for rule in separatedRulesList:

Page No. ………………….. Signature of the Faculty………………………...


Roll No:160122733163.. [Link] Date:24-02-2025………...

tempRule = [Link](rule)
tempRule[1].remove('.')
numbered[key_count] = tempRule
key_count += 1

# start REDUCE procedure


# format for follow computation
addedR = f"{separatedRulesList[0][0]} -> " \
f"{separatedRulesList[0][1][1]}"
[Link](0, addedR)
for rule in rules:
k = [Link]("->")

# remove un-necessary spaces


k[0] = k[0].strip()
k[1] = k[1].strip()
rhs = k[1]
multirhs = [Link]('|')

# remove un-necessary spaces


for i in range(len(multirhs)):
multirhs[i] = multirhs[i].strip()
multirhs[i] = multirhs[i].split()
diction[k[0]] = multirhs
for stateno in statesDict:
for rule in statesDict[stateno]:
if rule[1][-1] == '.':

# match the item


temp2 = [Link](rule)
temp2[1].remove('.')
for key in numbered:
if numbered[key] == temp2:

# put Rn in those ACTION symbol columns,


# who are in the follow of
# LHS of current Item.
follow_result = follow(rule[0])
for col in follow_result:
index = [Link](col)
if key == 0:
Table[stateno][index] = "Accept"
else:
Table[stateno][index] =\
Table[stateno][index]
+f"R{key} "
print("\nSLR(1) parsing table:\n")
frmt = "{:>8}" * len(cols)
print(" ", [Link](*cols), "\n")

Page No. ………………….. Signature of the Faculty………………………...


Roll No:160122733163.. [Link] Date:24-02-2025………...

ptr = 0
j=0
for y in Table:
frmt1 = "{:>8}" * len(y)
print(f"{{:>3}} {[Link](*y)}"
.format('I'+str(j)))
j += 1

def printResult(rules):
for rule in rules:
print(f"{rule[0]} ->"
f" {' '.join(rule[1])}")

def printAllGOTO(diction):
for itr in diction:
print(f"GOTO ( I{itr[0]} ,"
f" {itr[1]} ) = I{stateMap[itr]}")

rules = []
a=1
while True:
flag = input("do you want to stop giving productions(y/n): ")
if flag=='y':
break
else:
print("give the ",a," production: ")
a += 1
ans = input()
[Link](ans)
nonterm_userdef = input("give non terminals in production: ").split(" ")
term_userdef = input("give terminals in production: ").split(" ")
start_symbol = nonterm_userdef[0]

print("\nOriginal grammar input:\n")


for y in rules:
print(y)

# print processed rules


print("\nGrammar after Augmentation: \n")
separatedRulesList = \
grammarAugmentation(rules,
nonterm_userdef,
start_symbol)
printResult(separatedRulesList)

# find closure
start_symbol = separatedRulesList[0][0]
print("\nCalculated closure: I0\n")
I0 = findClosure(0, start_symbol)

Page No. ………………….. Signature of the Faculty………………………...


Roll No:160122733163.. [Link] Date:24-02-2025………...

printResult(I0)

statesDict = {}
stateMap = {}

statesDict[0] = I0
stateCount = 0

generateStates(statesDict)

# print goto states


print("\nStates Generated: \n")
for st in statesDict:
print(f"State = I{st}")
printResult(statesDict[st])
print()

print("Result of GOTO computation:\n")


printAllGOTO(stateMap)

# "follow computation" for making REDUCE entries


diction = {}

# call createParseTable function


createParseTable(statesDict, stateMap,
term_userdef,
nonterm_userdef)

Output1 :

Page No. ………………….. Signature of the Faculty………………………...


Roll No:160122733163.. [Link] Date:24-02-2025………...

Output 2:

Page No. ………………….. Signature of the Faculty………………………...


Roll No:160122733163.. [Link] Date:24-02-2025………...

Conclusion:

SLR(1) parsing is an efficient bottom-up parsing technique that ensures deterministic parsing
for a subset of context-free grammars. It systematically constructs the parsing table using
LR(0) items and FOLLOW sets. While powerful, SLR(1) may fail for grammars requiring
more lookahead, making LALR(1) and CLR(1) better choices for more complex cases.

[Link]: Write a program to implement parser for XML language using lex,yacc tool

Description: This program is an XML parser implemented using Lex (Flex) and Yacc
(Bison). It tokenizes and parses XML-like structures to check for syntax correctness. The
Lex file defines rules for recognizing XML tokens such as tags (<tag>) and text content,
while the Yacc file defines grammar rules to validate XML structure. The parser detects
opening and closing tags, ensures well-formed XML syntax, and extracts text content
between tags.

Algorithm:

1. Define Lex Rules:

 Ignore whitespace.
 Recognize opening (<tag>), closing (</tag>), and text content.

2. Define Yacc Rules:

 Define xml as the start symbol containing an element.


 Define an element with an opening tag, content, and closing tag.
 Capture and print text content inside the tags.

3. Handle Errors:

 Implement yyerror() to report syntax errors.

[Link] Input XML:

Page No. ………………….. Signature of the Faculty………………………...


Roll No:160122733163.. [Link] Date:24-02-2025………...

 Call yyparse() in main() to process input XML data.

Code:

Lex program:

%{
#include "[Link].h"
#include <string.h>
%}

%%

[ \t\n] ; // Ignore whitespace


"<" { return OPEN_TAG; }
"</" { return CLOSE_TAG; }
">" { return GT; }
[a-zA-Z0-9_]+ { [Link] = strdup(yytext); return TEXT; }

. { printf("Unexpected character: %s\n", yytext); }

%%

int yywrap() { return 1; }

Yacc program:

%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void yyerror(const char *s);


int yylex();
%}

%union {
char *str;
}

%token <str> TEXT


%token OPEN_TAG CLOSE_TAG GT

%%

xml:

Page No. ………………….. Signature of the Faculty………………………...


Roll No:160122733163.. [Link] Date:24-02-2025………...

element
;

element:
OPEN_TAG TEXT GT content CLOSE_TAG TEXT GT
{
printf("Parsed XML Element: <%s> ... </%s>\n", $2, $6);
free($2);
free($6);
}
;

content:
content TEXT { printf("Content: %s\n", $2); free($2); }
| /* empty */
;

%%

void yyerror(const char *s) {


fprintf(stderr, "Syntax Error: %s\n", s);
}

int main() {
printf("Enter XML data:\n");
yyparse();
return 0;

Output1:

Output2:

Conclusion:

Page No. ………………….. Signature of the Faculty………………………...


Roll No:160122733163.. [Link] Date:24-02-2025………...

This XML parser effectively validates well-formed XML structures using Lex and Yacc. It
ensures that each opening tag has a corresponding closing tag and that text content is properly
parsed. While basic, this parser can be extended to support nested elements, attributes, and
more complex XML structures, making it a useful foundation for XML processing
applications.

Page No. ………………….. Signature of the Faculty………………………...

You might also like