FIND TERMINALS AND NON-TERMINALS FROM FOLLOWING GRAMMER:
CODE:
import java.util.*;
public class CFGAnalyzer {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n;
while (true) {
try {
System.out.println("Enter the number of productions in the grammar:");
n = Integer.parseInt(scanner.nextLine());
break;
} catch (NumberFormatException e) {
System.out.println("Please enter a valid number.");
System.out.println("Enter the productions (one per line, e.g., S -> aB | b | ε):");
List<String> productions = new ArrayList<>();
for (int i = 0; i < n; i++) {
String production = scanner.nextLine().trim();
if (production.isEmpty()) {
System.out.println("Empty production is not allowed. Try again:");
i--;
} else {
productions.add(production);
}
Set<String> nonTerminals = new HashSet<>();
Set<String> terminals = new HashSet<>();
for (String production : productions) {
String[] parts = production.split("->");
if (parts.length != 2) {
System.out.println("Invalid production format: " + production);
continue;
String lhs = parts[0].trim();
String rhs = parts[1].trim();
nonTerminals.add(lhs);
String[] rhsRules = rhs.split("\\|");
for (String rule : rhsRules) {
for (char symbol : rule.trim().toCharArray()) {
String sym = String.valueOf(symbol);
if (Character.isUpperCase(symbol)) {
nonTerminals.add(sym);
} else if (!sym.equals("ε")) {
terminals.add(sym);
terminals.removeAll(nonTerminals);
System.out.println("Non-Terminals: " + nonTerminals);
System.out.println("Terminals: " + terminals);
LEXICAL ANALYSER (C CODE):
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#define BUFFERLEN 100;
#define KW_MAX 12;
const char
keywords[12][10]={"auto","int","float","char","for","while","return","void","if","else","main","dowhile"};
const char operators[]="<>=+-*/";
const char special_characters[]="{}();,";
int isKeyword(char word[]){
for(int i=0;i<12;i++){
if(strcmp(word,keywords[i])==0){
return 1;
return 0;
}
void lex(char input[]){
char ch;
char buffer[100];
int buffer_ptr=0;
for(int i=0;input[i]!='\0';i++){
ch=input[i];
if(isalnum(ch)){
buffer[buffer_ptr]=ch;
buffer_ptr++;
else{
if(buffer_ptr>0){
buffer[buffer_ptr]='\0';
if(isdigit(buffer[0])){
printf("Digit: %s\n",buffer);
else if(isKeyword(buffer)){
printf("Keyword: %s\n",buffer);
else {
printf("Identifier: %s\n",buffer);
buffer_ptr=0;
if(strchr(operators,ch)){
printf("Operator: %c\n",ch);
else if(strchr(special_characters,ch)){
printf("Special characters: %c\n",ch);
}
if(buffer_ptr>0){
buffer[buffer_ptr]='\0';
if(isdigit(buffer[0])){
printf("Digit: %s\n",buffer);
else if(isKeyword(buffer)){
printf("Keyword: %s\n",buffer);
else {
printf("Identifier: %s\n",buffer);
int main(){
char program[100 * 10] =
"int main() {\n"
" int x = 10 + 20;\n"
" float y = x * 2.5;\n"
" if (y > 30) {\n"
" return 0;\n"
" }\n"
"}";
printf("Input Program:\n%s\n\nTokens:\n", program);
lex(program);
JAVA CODE FOR PRINTING WORDS LENGTH MORE THAN FOUR:
CODE:
import java.io.*;
import java.util.*;
import java.util.regex.*;
public class WordLengthFinder {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the source code (end input with an empty line):");
StringBuilder sourceCode = new StringBuilder();
while (true) {
String line = scanner.nextLine();
if (line.isEmpty()) break;
sourceCode.append(line).append("\n");
Pattern wordPattern = Pattern.compile("\\b\\w{5,}\\b");
Matcher matcher = wordPattern.matcher(sourceCode.toString());
Set<String> words = new HashSet<>();
while (matcher.find()) {
words.add(matcher.group());
System.out.println("Words with length greater than 4:");
for (String word : words) {
System.out.println(word);
}
SYMBOL TABLE:
#include<stdio.h>
#include<ctype.h>
#include<string.h>
typedef struct{
char name[30];
char type[20];
}Symbol;
Symbol sx[100];
int sx_count=0;
const char keywords[12][10] = {"auto", "int", "float", "char", "for", "while", "return", "void", "if", "else",
"main", "dowhile"};
const char sp_char[] = "(){};,+-*/=<>";
char types[]="int|float|bool|char";
int notKeyword(char word[]){
for(int i=0;i<12;i++){
if(strcmp(word,keywords[i])==0){
return 0;
return 1;
}
int isType(char word[]){
return(strstr(types,word)!=NULL);
void addSymbol(char name[],char type[]){
strcpy(sx[sx_count].name,name);
strcpy(sx[sx_count].type,type);
sx_count++;
void lex(char input[]){
char ch,buffer[100],cur_type[20];
int buffer_ptr=0;
for(int i=0;input[i]!='\0';i++){
ch=input[i];
if(isalnum(ch)){
buffer[buffer_ptr++]=ch;
else{
if(buffer_ptr>0){
buffer[buffer_ptr]='\0';
if(isType(buffer)){
strcpy(cur_type,buffer);
else if(notKeyword(buffer)){
addSymbol(buffer,cur_type);
}
buffer_ptr=0;
else if(strchr(sp_char,ch)){
printf("Symbol: %c\n",ch);
if(buffer_ptr>0){
buffer[buffer_ptr]='\0';
if(notKeyword(buffer)){
addSymbol(buffer,cur_type);
void printTable(){
printf("Name\tType\n");
for (int i = 0; i < sx_count; i++) {
printf("%s\t%s\n", sx[i].name, sx[i].type);
int main() {
char program[] =
"int main() {\n"
" int x = 10;\n"
" float y = x * 2.5;\n"
" char c = 'A';\n"
" if (y > 30) { return 0; }\n"
"}";
lex(program);
printTable();
return 0;
Recursive Descent parsing:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
static final int MAX_LEN = 100;
static String input;
static List<String> tokens = new ArrayList<>();
static int current = 0;
static void tokenize() {
int i = 0;
while (i < input.length()) {
if (input.startsWith("int", i)) {
tokens.add("int");
i += 3;
} else if (input.charAt(i) == '+' || input.charAt(i) == '*' || input.charAt(i) == '(' ||
input.charAt(i) == ')') {
tokens.add(String.valueOf(input.charAt(i)));
i++;
} else if (Character.isWhitespace(input.charAt(i))) {
i++;
} else {
tokens.add("INVALID");
i++;
}
}
}
static void advance() {
if (current < tokens.size()) {
current++;
}
}
static boolean match(String expected) {
if (current < tokens.size() && tokens.get(current).equals(expected)) {
advance();
return true;
}
return false;
}
static boolean E() {
int saved_pos = current;
if (T()) {
if (match("+")) {
if (E()) {
return true;
} else {
current = saved_pos;
return false;
}
}
return true;
}
current = saved_pos;
return false;
}
static boolean T() {
int saved_pos = current;
if (match("int")) {
if (match("*")) {
if (T()) {
return true;
} else {
current = saved_pos;
return false;
}
}
return true;
}
if (match("(")) {
if (E()) {
if (match(")")) {
return true;
} else {
current = saved_pos;
return false;
}
}
current = saved_pos;
return false;
}
current = saved_pos;
return false;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
input = scanner.nextLine();
tokenize();
for (String token : tokens) {
if (token.equals("INVALID")) {
System.out.println("String is not accepted");
return;
}
}
if (E() && current == tokens.size()) {
System.out.println("String is accepted");
} else {
System.out.println("String is not accepted");
}
scanner.close();
}
}
OPERATOR PRECEDENCE:
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#define MAX_STACK_SIZE 30
// Operator precedence table (q) initialization
char precedence[9][9] = {
{'>', '>', '<', '<', '<', '<', '>', '<', '>'}, // 0
{'>', '>', '<', '<', '<', '<', '>', '<', '>'}, // 1
{'>', '>', '>', '>', '<', '<', '>', '<', '>'}, // 2
{'>', '>', '>', '>', '<', '<', '>', '<', '>'}, // 3
{'>', '>', '<', '<', '<', '<', '>', '<', '>'}, // 4
{'<', '<', '<', '<', '<', '<', '=', '<', 'E'}, // 5
{'>', '>', '>', '>', '>', 'E', '>', 'E', '>'}, // 6
{'>', '>', '>', '>', '>', 'E', '>', 'E', '>'}, // 7
{'<', '<', '<', '<', '<', '<', 'E', '<', 'A'} // 8
};
char input[100]; // Input expression string
char stack[MAX_STACK_SIZE]; // Stack to hold operators and operands
char reduce_stack[MAX_STACK_SIZE]; // Stack for reductions
int top = -1; // Stack pointer
int p = 0; // Input pointer
int r = -1; // Reduce stack pointer
// Function to push an element onto the stack
void push(char a) {
if (top < MAX_STACK_SIZE - 1) {
top++;
stack[top] = a;
} else {
printf("Stack overflow\n");
// Function to pop an element from the stack
char pop() {
if (top >= 0) {
char a = stack[top];
top--;
return a;
} else {
printf("Stack underflow\n");
return '\0';
// Function to find the index of operators and operands
int find(char a) {
switch(a) {
case '+': return 0;
case '-': return 1;
case '*': return 2;
case '/': return 3;
case '^': return 4;
case '(': return 5;
case ')': return 6;
case 'a': return 7; // For operands (a-zA-Z)
case '$': return 8; // End of input
default: return -1; // Invalid character
// Function to display shift operations
void display(char a) {
printf("\nShift %c", a);
// Function to display reduce operations
void display1(char a) {
if (isalpha(a))
printf("\nReduce E->%c", a);
else if (a == '+' || a == '-' || a == '*' || a == '/' || a == '^')
printf("\nReduce E->E%cE", a);
else if (a == ')')
printf("\nReduce E->(E)");
}
// Function to check precedence relation between operators
int rel(char a, char b, char d) {
if (isalpha(a)) a = 'a';
if (isalpha(b)) b = 'a';
if (precedence[find(a)][find(b)] == d)
return 1;
else
return 0;
// Main function for the operator precedence parser
int main() {
printf("Operator Precedence Parser\n");
printf("Enter the Arithmetic Expression (end with $): ");
// Safe input handling using fgets
fgets(input, sizeof(input), stdin);
input[strcspn(input, "\n")] = '\0'; // Remove newline character
push('$'); // Push end of input marker to stack
int i = 0; // Input pointer
while (1) {
if (input[p] == '$' && stack[top] == '$') {
printf("\nAccepted");
break;
}
else if (rel(stack[top], input[p], '<') || rel(stack[top], input[p], '=')) {
display(input[p]);
push(input[p]);
p++;
else if (rel(stack[top], input[p], '>')) {
do {
r++;
reduce_stack[r] = pop();
display1(reduce_stack[r]);
} while (!rel(stack[top], reduce_stack[r], '<'));
return 0;
FIRST AND FOLLOW OF THE GRAMMER;
#include <ctype.h>
#include <stdio.h>
#include <string.h>
void followfirst(char, int, int);
void follow(char c);
void findfirst(char, int, int);
int count, n = 0;
char calc_first[10][100];
char calc_follow[10][100];
int m = 0;
char production[10][10];
char f[10], first[10];
int k;
char ck;
int e;
int main(int argc, char** argv) {
int jm = 0;
int km = 0;
int i, choice;
char c, ch;
count = 8;
strcpy(production[0], "X=TnS");
strcpy(production[1], "X=Rm");
strcpy(production[2], "T=q");
strcpy(production[3], "T=#");
strcpy(production[4], "S=p");
strcpy(production[5], "S=#");
strcpy(production[6], "R=om");
strcpy(production[7], "R=ST");
int kay;
char done[count];
int ptr = -1;
for (k = 0; k < count; k++) {
for (kay = 0; kay < 100; kay++) {
calc_first[k][kay] = '!';
}
}
int point1 = 0, point2, xxx;
for (k = 0; k < count; k++) {
c = production[k][0];
point2 = 0;
xxx = 0;
for (kay = 0; kay <= ptr; kay++)
if (c == done[kay])
xxx = 1;
if (xxx == 1)
continue;
findfirst(c, 0, 0);
ptr += 1;
done[ptr] = c;
printf("\n First(%c) = { ", c);
calc_first[point1][point2++] = c;
for (i = 0 + jm; i < n; i++) {
int lark = 0, chk = 0;
for (lark = 0; lark < point2; lark++) {
if (first[i] == calc_first[point1][lark]) {
chk = 1;
break;
}
}
if (chk == 0) {
printf("%c, ", first[i]);
calc_first[point1][point2++] = first[i];
}
}
printf("}\n");
jm = n;
point1++;
}
printf("\n");
printf("-----------------------------------------------"
"\n\n");
char donee[count];
ptr = -1;
for (k = 0; k < count; k++) {
for (kay = 0; kay < 100; kay++) {
calc_follow[k][kay] = '!';
}
}
point1 = 0;
int land = 0;
for (e = 0; e < count; e++) {
ck = production[e][0];
point2 = 0;
xxx = 0;
for (kay = 0; kay <= ptr; kay++)
if (ck == donee[kay])
xxx = 1;
if (xxx == 1)
continue;
land += 1;
follow(ck);
ptr += 1;
donee[ptr] = ck;
printf(" Follow(%c) = { ", ck);
calc_follow[point1][point2++] = ck;
for (i = 0 + km; i < m; i++) {
int lark = 0, chk = 0;
for (lark = 0; lark < point2; lark++) {
if (f[i] == calc_follow[point1][lark]) {
chk = 1;
break;
}
}
if (chk == 0) {
printf("%c, ", f[i]);
calc_follow[point1][point2++] = f[i];
}
}
printf(" }\n\n");
km = m;
point1++;
}
}
void follow(char c) {
int i, j;
if (production[0][0] == c) {
f[m++] = '$';
}
for (i = 0; i < 10; i++) {
for (j = 2; j < 10; j++) {
if (production[i][j] == c) {
if (production[i][j + 1] != '\0') {
followfirst(production[i][j + 1], i,
(j + 2));
}
if (production[i][j + 1] == '\0'
&& c != production[i][0]) {
follow(production[i][0]);
}
}
}
}
}
void findfirst(char c, int q1, int q2) {
int j;
if (!(isupper(c))) {
first[n++] = c;
}
for (j = 0; j < count; j++) {
if (production[j][0] == c) {
if (production[j][2] == '#') {
if (production[q1][q2] == '\0')
first[n++] = '#';
else if (production[q1][q2] != '\0'
&& (q1 != 0 || q2 != 0)) {
findfirst(production[q1][q2], q1,
(q2 + 1));
}
else
first[n++] = '#';
}
else if (!isupper(production[j][2])) {
first[n++] = production[j][2];
}
else {
findfirst(production[j][2], j, 3);
}
}
}
}
void followfirst(char c, int c1, int c2) {
int k;
if (!(isupper(c)))
f[m++] = c;
else {
int i = 0, j = 1;
for (i = 0; i < count; i++) {
if (calc_first[i][0] == c)
break;
}
while (calc_first[i][j] != '!') {
if (calc_first[i][j] != '#') {
f[m++] = calc_first[i][j];
}
else {
if (production[c1][c2] == '\0') {
follow(production[c1][0]);
}
else {
followfirst(production[c1][c2], c1,
c2 + 1);
}
}
j++;
}
}
}