1.
write a c program to test whether given entered string within valid comment section or
not
#include <stdio.h>
#include <string.h>
int main() {
char str[500];
char choice;
do {
printf("\nEnter a string: ");
fgets(str, sizeof(str), stdin);
str[strcspn(str, "\n")] = '\0';
int len = strlen(str);
// Check for single-line comment //
if (len >= 2 && str[0] == '/' && str[1] == '/') {
printf("Valid single-line comment.\n");
// Check for multi-line comment /* ... */
else if (len >= 4 && str[0] == '/' && str[1] == '*' && str[len-2] == '*' && str[len-1] == '/') {
printf("Valid multi-line comment.\n");
else {
printf("Not a valid comment.\n");
}
printf("Do you want to check another string? (y/n): ");
scanf(" %c", &choice);
getchar();
} while (choice == 'y' || choice == 'Y');
printf("Program ended.\n");
return 0;
Output:
2. Write a program to recognize strings under 'a*','a*b+','abb'
#include <stdio.h>
#include <string.h>
int isAStar(char str[]) {
for (int i = 0; str[i] != '\0'; i++)
if (str[i] != 'a') return 0;
return 1;
int isABPlus(char str[]) {
int i = 0;
while (str[i] == 'a') i++;
int bCount = 0;
while (str[i] == 'b') {
i++;
bCount++;
if (bCount >= 1 && str[i] == '\0') return 1;
return 0;
int isABB(char str[]) {
return strcmp(str, "abb") == 0;
int main() {
char str[100];
char choice;
do {
printf("\nEnter a string: ");
scanf("%s", str);
if (isAStar(str))
printf("String matches pattern: a*\n");
else if (isABPlus(str))
printf("String matches pattern: a*b+\n");
else if (isABB(str))
printf("String matches pattern: abb\n");
else
printf("String does not match any pattern.\n");
printf("Do you want to check another string? (y/n): ");
scanf(" %c", &choice);
} while (choice == 'y' || choice == 'Y');
printf("Program ended.\n");
return 0;
}
3. c program to test whether a given identifier is valid or not
#include <stdio.h>
#include <ctype.h>
#include <string.h>
const char *keywords[] = {
"auto","break","case","char","const","continue","default","do","double",
"else","enum","extern","float","for","goto","if","int","long","register",
"return","short","signed","sizeof","static","struct","switch","typedef",
"union","unsigned","void","volatile","while"
};
int isKeyword(char str[]) {
for (int i = 0; i < sizeof(keywords)/sizeof(keywords[0]); i++) {
if (strcmp(str, keywords[i]) == 0)
return 1;
return 0;
int isValidIdentifier(char str[]) {
int len = strlen(str);
if (len == 0) return 0;
if (!isalpha(str[0]) && str[0] != '_') return 0;
for (int i = 1; i < len; i++) {
if (!isalnum(str[i]) && str[i] != '_') return 0;
}
if (isKeyword(str)) return 0;
return 1;
int main() {
char str[100];
char choice;
do {
printf("\nEnter an identifier: ");
scanf("%s", str);
if (isValidIdentifier(str))
printf("'%s' is a valid identifier.\n", str);
else
printf("'%s' is NOT a valid identifier.\n", str);
printf("Do you want to check another identifier? (y/n): ");
scanf(" %c", &choice);
} while (choice == 'y' || choice == 'Y');
printf("Program ended.\n");
return 0;
}
4. write a c program for lexical analyzer
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
char *keywords[] = {
"int", "float", "double", "char", "void", "if", "else", "while",
"for", "return", "do", "switch", "case", "break", "continue"
};
#define NUM_KEYWORDS (sizeof(keywords) / sizeof(keywords[0]))
int isKeyword(char *str) {
for (int i = 0; i < NUM_KEYWORDS; i++) {
if (strcmp(str, keywords[i]) == 0)
return 1;
return 0;
int isIdentifier(char *str) {
if (!isalpha(str[0]) && str[0] != '_')
return 0;
for (int i = 1; str[i]; i++) {
if (!isalnum(str[i]) && str[i] != '_')
return 0;
return 1;
void lexicalAnalyzer(FILE *fp) {
char ch, str[100];
int i, state = 0;
printf("TOKENS:\n");
printf("-------\n");
while ((ch = fgetc(fp)) != EOF) {
switch (state) {
case 0:
if (isalpha(ch) || ch == '_') {
str[0] = ch;
i = 1;
state = 1;
else if (isdigit(ch)) {
str[0] = ch;
i = 1;
state = 2;
else if (ch == '\"') {
state = 3; // String literal
printf("STRING: ");
else if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '=') {
printf("OPERATOR: %c\n", ch);
else if (ch == ';' || ch == ',' || ch == '(' || ch == ')' || ch == '{' || ch == '}' || ch == '[' ||
ch == ']') {
printf("PUNCTUATION: %c\n", ch);
else if (isspace(ch)) {
else {
printf("UNKNOWN: %c\n", ch);
break;
case 1:
if (isalnum(ch) || ch == '_') {
str[i++] = ch;
} else {
str[i] = '\0';
if (isKeyword(str)) {
printf("KEYWORD: %s\n", str);
} else if (isIdentifier(str)) {
printf("IDENTIFIER: %s\n", str);
} else {
printf("INVALID IDENTIFIER: %s\n", str);
state = 0;
ungetc(ch, fp);
break;
case 2:
if (isdigit(ch)) {
str[i++] = ch;
} else {
str[i] = '\0';
printf("CONSTANT: %s\n", str);
state = 0;
ungetc(ch, fp);
break;
case 3:
if (ch == '\"') {
printf("\"\n");
state = 0;
} else if (ch == '\\') {
printf("%c", ch);
ch = fgetc(fp);
printf("%c", ch);
} else {
printf("%c", ch);
break;
if (state == 1) {
str[i] = '\0';
if (isKeyword(str)) {
printf("KEYWORD: %s\n", str);
} else {
printf("IDENTIFIER: %s\n", str);
} else if (state == 2) {
str[i] = '\0';
printf("CONSTANT: %s\n", str);
} else if (state == 3) {
printf("\"\n");
printf("ERROR: Unterminated string\n");
}
int main() {
FILE *fp = fopen("input.txt", "r");
if (fp == NULL) {
printf("Error: Could not open input.txt\n");
return 1;
lexicalAnalyzer(fp);
fclose(fp);
return 0;
*create a file named input.txt with sample code
int main() {
int a = 10;
float b = 3.14;
a = a + 1;
return 0;
}
5. C program to implement first of a given grammar
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAX 20
char production[MAX][MAX], firstSet[MAX];
int n;
int m = 0;
void findFirst(char c);
void addToFirstSet(char c);
int main() {
int i;
char choice, c;
printf("Enter number of productions: ");
scanf("%d", &n);
printf("Enter the productions (E.g. E=E+T):\n");
for (i = 0; i < n; i++) {
scanf("%s", production[i]);
do {
m = 0;
printf("\nEnter the non-terminal to find FIRST: ");
scanf(" %c", &c);
findFirst(c);
printf("FIRST(%c) = { ", c);
for (i = 0; i < m; i++) {
printf("%c ", firstSet[i]);
printf("}\n");
printf("\nDo you want to continue? (y/n): ");
scanf(" %c", &choice);
} while (choice == 'y' || choice == 'Y');
return 0;
}
void findFirst(char c) {
int i, j;
if (!(isupper(c))) {
addToFirstSet(c);
return;
for (i = 0; i < n; i++) {
if (production[i][0] == c) {
if (production[i][2] == '#') {
// Epsilon production
addToFirstSet('#');
else if (!isupper(production[i][2])) {
// Terminal
addToFirstSet(production[i][2]);
else {
findFirst(production[i][2]);
}
void addToFirstSet(char c) {
int i;
for (i = 0; i < m; i++) {
if (firstSet[i] == c)
return;
firstSet[m++] = c;
6. c program to calculate Follow(A)
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX 20
char production[MAX][MAX], followSet[MAX], firstSet[MAX];
int n;
int m = 0;
char startSymbol;
void findFirst(char c);
void findFollow(char c);
void addToFirstSet(char c);
void addToFollowSet(char c);
int main() {
int i;
char c, choice;
printf("Enter number of productions: ");
scanf("%d", &n);
printf("Enter the productions (e.g., E=E+T):\n");
for (i = 0; i < n; i++) {
scanf("%s", production[i]);
startSymbol = production[0][0]; // first LHS is start symbol
do {
m = 0;
printf("\nEnter the non-terminal to find FOLLOW: ");
scanf(" %c", &c);
findFollow(c);
printf("FOLLOW(%c) = { ", c);
for (i = 0; i < m; i++) {
printf("%c ", followSet[i]);
printf("}\n");
printf("\nDo you want to continue? (y/n): ");
scanf(" %c", &choice);
} while (choice == 'y' || choice == 'Y');
return 0;
void findFirst(char c) {
int i;
if (!isupper(c)) {
addToFirstSet(c);
return;
for (i = 0; i < n; i++) {
if (production[i][0] == c) {
if (production[i][2] == '#') {
addToFirstSet('#');
} else if (!isupper(production[i][2])) {
addToFirstSet(production[i][2]);
} else {
findFirst(production[i][2]);
}
void findFollow(char c) {
int i, j, k;
if (c == startSymbol) {
addToFollowSet('$'); // Rule 1
for (i = 0; i < n; i++) {
for (j = 2; j < strlen(production[i]); j++) {
if (production[i][j] == c) {
if (production[i][j + 1] != '\0') {
if (!isupper(production[i][j + 1])) {
addToFollowSet(production[i][j + 1]);
} else {
m = 0;
findFirst(production[i][j + 1]);
for (k = 0; k < m; k++) {
if (firstSet[k] != '#')
addToFollowSet(firstSet[k]);
else {
findFollow(production[i][0]); // Rule 3
}
}
} else {
// Case A -> aB
if (production[i][0] != c) {
findFollow(production[i][0]);
void addToFirstSet(char c) {
int i;
for (i = 0; i < m; i++) {
if (firstSet[i] == c) return;
firstSet[m++] = c;
void addToFollowSet(char c) {
int i;
for (i = 0; i < m; i++) {
if (followSet[i] == c) return;
followSet[m++] = c;
}
7. c program for constructing of LL(1) parsing
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX 50
char productions[MAX][MAX], nonTerminals[MAX], terminals[MAX];
int prodCount = 0, ntCount = 0, tCount = 0;
char table[MAX][MAX][MAX]; // LL(1) parsing table
// FIRST and FOLLOW sets
char firstSet[MAX][MAX], followSet[MAX][MAX];
int isIn(char *set, char c) {
for (int i = 0; set[i]; i++) if (set[i] == c) return 1;
return 0;
void addToSet(char *set, char c) {
if (!isIn(set, c)) {
int len = strlen(set);
set[len] = c;
set[len+1] = '\0';
void computeFirst(char symbol, char *result) {
if (!isupper(symbol)) { // terminal
addToSet(result, symbol);
return;
for (int i = 0; i < prodCount; i++) {
if (productions[i][0] == symbol) {
if (productions[i][2] == '#') {
addToSet(result, '#');
} else {
for (int j = 2; productions[i][j]; j++) {
char temp[MAX] = "";
computeFirst(productions[i][j], temp);
for (int k = 0; temp[k]; k++) {
if (temp[k] != '#')
addToSet(result, temp[k]);
if (!isIn(temp, '#')) break;
if (!productions[i][j+1])
addToSet(result, '#');
}
void computeFollow(char symbol, char *result) {
if (symbol == productions[0][0]) addToSet(result, '$'); // start symbol
for (int i = 0; i < prodCount; i++) {
for (int j = 2; productions[i][j]; j++) {
if (productions[i][j] == symbol) {
if (productions[i][j+1]) {
char temp[MAX] = "";
computeFirst(productions[i][j+1], temp);
for (int k = 0; temp[k]; k++) {
if (temp[k] != '#')
addToSet(result, temp[k]);
if (isIn(temp, '#'))
computeFollow(productions[i][0], result);
} else if (productions[i][j] != productions[i][0]) {
computeFollow(productions[i][0], result);
}
}
void buildTable() {
for (int i = 0; i < ntCount; i++)
for (int j = 0; j < tCount; j++)
strcpy(table[i][j], " ");
for (int i = 0; i < prodCount; i++) {
char A = productions[i][0];
char rhs[MAX];
strcpy(rhs, productions[i] + 2);
char first[MAX] = "";
computeFirst(rhs[0], first);
int row = strchr(nonTerminals, A) - nonTerminals;
for (int k = 0; first[k]; k++) {
if (first[k] != '#') {
char *ptr = strchr(terminals, first[k]);
if (ptr) {
int col = ptr - terminals;
strcpy(table[row][col], productions[i]);
} else {
char follow[MAX] = "";
computeFollow(A, follow);
for (int m = 0; follow[m]; m++) {
char *ptr = strchr(terminals, follow[m]);
if (ptr) {
int col = ptr - terminals;
strcpy(table[row][col], productions[i]);
void printTable() {
printf("\nLL(1) Parsing Table:\n\t");
for (int j = 0; j < tCount; j++) printf("%c\t", terminals[j]);
printf("\n");
for (int i = 0; i < ntCount; i++) {
printf("%c\t", nonTerminals[i]);
for (int j = 0; j < tCount; j++) {
printf("%s\t", table[i][j]);
printf("\n");
int parseString(char *input) {
char stack[MAX] = "$";
stack[1] = productions[0][0];
stack[2] = '\0';
int top = 1; // points to stack top
printf("\nParsing steps:\n");
int ip = 0;
while (1) {
printf("Stack: %s | Input: %s | ", stack, input+ip);
char X = stack[top];
char a = input[ip];
if (X == '$' && a == '$') {
printf("Accept\n");
return 1;
} else if (!isupper(X)) { // terminal
if (X == a) {
printf("Match %c\n", a);
top--; stack[top+1] = '\0';
ip++;
} else {
printf("Error (expected %c, got %c)\n", X, a);
return 0;
} else {
char *rowPtr = strchr(nonTerminals, X);
char *colPtr = strchr(terminals, a);
if (!rowPtr || !colPtr) {
printf("Error (no rule for %c,%c)\n", X, a);
return 0;
int row = rowPtr - nonTerminals;
int col = colPtr - terminals;
if (strcmp(table[row][col], " ") == 0) {
printf("Error (no rule for %c,%c)\n", X, a);
return 0;
} else {
printf("Output %s\n", table[row][col]);
top--; stack[top+1] = '\0';
char rhs[MAX];
strcpy(rhs, table[row][col] + 2);
if (!(rhs[0] == '#' && rhs[1] == '\0')) {
int len = strlen(rhs);
for (int k = len-1; k >= 0; k--) {
top++;
stack[top] = rhs[k];
stack[top+1] = '\0';
}
}
int main() {
printf("Enter number of productions: ");
scanf("%d", &prodCount);
getchar();
for (int i = 0; i < prodCount; i++) {
printf("Enter production %d: ", i+1);
scanf("%s", productions[i]);
if (!isIn(nonTerminals, productions[i][0])) {
nonTerminals[ntCount++] = productions[i][0];
nonTerminals[ntCount] = '\0';
for (int j = 2; productions[i][j]; j++) {
if (!isupper(productions[i][j]) && productions[i][j] != '#') {
if (!isIn(terminals, productions[i][j])) {
terminals[tCount++] = productions[i][j];
terminals[tCount] = '\0';
}
}
terminals[tCount++] = '$'; terminals[tCount] = '\0';
buildTable();
printTable();
char input[MAX];
printf("\nEnter a string to parse (end with $): ");
scanf("%s", input);
if (parseString(input))
printf("\nString accepted.\n");
else
printf("\nString rejected.\n");
return 0;
}
8. c program to implement shift reducer parser
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 100
char input[MAX];
char stack[MAX];
int top = -1;
int ip = 0;
void push(char c) {
stack[++top] = c;
stack[top+1] = '\0';
}
void pop(int n) {
top -= n;
if (top < -1) top = -1;
stack[top+1] = '\0';
void printStep(const char *action) {
printf("Stack: %-20s Input: %-20s Action: %s\n", stack, input + ip, action);
int reduce() {
// Rule: E ? id
if (top >= 1 && stack[top] == 'd' && stack[top-1] == 'i') {
pop(2);
push('E');
printStep("Reduce: id ? E");
return 1;
// Rule: E ? (E)
if (top >= 2 && stack[top] == ')' && stack[top-2] == '(' && stack[top-1] == 'E') {
pop(3);
push('E');
printStep("Reduce: (E) ? E");
return 1;
// Rule: E ? E+E
if (top >= 2 && stack[top] == 'E' && stack[top-2] == 'E' && stack[top-1] == '+') {
pop(3);
push('E');
printStep("Reduce: E+E ? E");
return 1;
// Rule: E ? E*E
if (top >= 2 && stack[top] == 'E' && stack[top-2] == 'E' && stack[top-1] == '*') {
pop(3);
push('E');
printStep("Reduce: E*E ? E");
return 1;
return 0;
int main() {
printf("Enter the input string (use id for identifiers, end with $): ");
scanf("%s", input);
printf("\nSHIFT-REDUCE Parsing Process:\n");
while (input[ip] != '\0') {
push(input[ip++]);
printStep("Shift");
while (reduce());
if (top == 0 && stack[0] == 'E') {
printf("\nString Accepted!\n");
} else {
printf("\nString Rejected!\n");
return 0;
9. c program for intermediate code generation
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int tempCount = 1;
char *newTemp() {
static char buffer[10];
sprintf(buffer, "t%d", tempCount++);
return buffer;
}
int precedence(char op) {
if (op == '*' || op == '/')
return 2;
if (op == '+' || op == '-')
return 1;
return 0;
void infixToPostfix(char infix[], char postfix[]) {
char stack[50];
int top = -1, k = 0;
for (int i = 0; i < strlen(infix); i++) {
char ch = infix[i];
if (isalnum(ch)) {
postfix[k++] = ch;
} else if (ch == '(') {
stack[++top] = ch;
} else if (ch == ')') {
while (top != -1 && stack[top] != '(')
postfix[k++] = stack[top--];
top--; // Pop '('
} else { // Operator
while (top != -1 && precedence(stack[top]) >= precedence(ch))
postfix[k++] = stack[top--];
stack[++top] = ch;
}
}
while (top != -1)
postfix[k++] = stack[top--];
postfix[k] = '\0';
void generateTAC(char postfix[]) {
char stack[50][10];
int top = -1;
for (int i = 0; i < strlen(postfix); i++) {
char ch = postfix[i];
if (isalnum(ch)) {
char op[2] = {ch, '\0'};
strcpy(stack[++top], op);
} else {
char op2[10], op1[10], result[10];
strcpy(op2, stack[top--]);
strcpy(op1, stack[top--]);
strcpy(result, newTemp());
printf("%s = %s %c %s\n", result, op1, ch, op2);
strcpy(stack[++top], result);
printf("Result stored in: %s\n", stack[top]);
}
int main() {
char infix[50], postfix[50];
printf("Enter an arithmetic expression (without spaces): ");
scanf("%s", infix);
infixToPostfix(infix, postfix);
printf("\nPostfix Expression: %s\n", postfix);
printf("\nThree Address Code (TAC):\n");
generateTAC(postfix);
return 0;
10. c program for final code generation
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int tempCount = 1;
char *newTemp() {
static char buffer[10];
sprintf(buffer, "t%d", tempCount++);
return buffer;
int precedence(char op) {
if (op == '*' || op == '/') return 2;
if (op == '+' || op == '-') return 1;
return 0;
void infixToPostfix(char infix[], char postfix[]) {
char stack[50];
int top = -1, k = 0;
for (int i = 0; i < strlen(infix); i++) {
char ch = infix[i];
if (isalnum(ch)) {
postfix[k++] = ch;
} else if (ch == '(') {
stack[++top] = ch;
} else if (ch == ')') {
while (top != -1 && stack[top] != '(')
postfix[k++] = stack[top--];
top--;
} else {
while (top != -1 && precedence(stack[top]) >= precedence(ch))
postfix[k++] = stack[top--];
stack[++top] = ch;
while (top != -1)
postfix[k++] = stack[top--];
postfix[k] = '\0';
void generateTAC(char postfix[], char tac[][50], int *tacLines) {
char stack[50][10];
int top = -1;
for (int i = 0; i < strlen(postfix); i++) {
char ch = postfix[i];
if (isalnum(ch)) {
char op[2] = {ch, '\0'};
strcpy(stack[++top], op);
} else {
char op2[10], op1[10], temp[10];
strcpy(op2, stack[top--]);
strcpy(op1, stack[top--]);
strcpy(temp, newTemp());
sprintf(tac[*tacLines], "%s = %s %c %s", temp, op1, ch, op2);
(*tacLines)++;
strcpy(stack[++top], temp);
void generateFinalCode(char tac[][50], int tacLines) {
printf("\nFinal Code (Assembly-like):\n");
for (int i = 0; i < tacLines; i++) {
char lhs[10], op1[10], op2[10], optr;
sscanf(tac[i], "%s = %s %c %s", lhs, op1, &optr, op2);
printf("MOV R0, %s\n", op1);
switch(optr) {
case '+': printf("ADD R0, %s\n", op2); break;
case '-': printf("SUB R0, %s\n", op2); break;
case '*': printf("MUL R0, %s\n", op2); break;
case '/': printf("DIV R0, %s\n", op2); break;
printf("MOV %s, R0\n\n", lhs);
}
int main() {
char infix[50], postfix[50];
char tac[50][50];
int tacLines = 0;
printf("Enter arithmetic expression (e.g., a+b*c-d): ");
scanf("%s", infix);
infixToPostfix(infix, postfix);
printf("Postfix Expression: %s\n", postfix);
generateTAC(postfix, tac, &tacLines);
printf("\nThree Address Code (TAC):\n");
for (int i = 0; i < tacLines; i++)
printf("%s\n", tac[i]);
generateFinalCode(tac, tacLines);
return 0;