Skip to main content

15.Design and implement a recursive descent parser for a given grammar.



Designing and implementing a recursive descent parser involves breaking down the grammar into recursive functions that correspond to its production rules. Each function handles a non-terminal symbol in the grammar and recursively calls other functions to parse the input based on the grammar rules. Here's an example of a simple recursive descent parser for a grammar that recognizes arithmetic expressions with + and * operators and parentheses:


```c

#include <stdio.h>

#include <ctype.h>


// Global variables

char input[100];

int position = 0;


// Function to consume a character from the input

char getNextChar() {

    return input[position++];

}


// Function to parse and evaluate a factor

int factor();


// Function to parse and evaluate a term

int term();


// Function to parse and evaluate an expression

int expression();


int main() {

    printf("Enter an arithmetic expression: ");

    scanf("%s", input);


    int result = expression();


    if (input[position] == '\0') {

        printf("Result: %d\n", result);

    } else {

        printf("Error in parsing.\n");

    }


    return 0;

}


int factor() {

    char c = getNextChar();

    if (isdigit(c)) {

        return c - '0';

    } else if (c == '(') {

        int result = expression();

        if (getNextChar() == ')') {

            return result;

        }

    }

    return 0; // Error case

}


int term() {

    int left = factor();

    while (input[position] == '*') {

        char op = getNextChar();

        int right = factor();

        left *= right;

    }

    return left;

}


int expression() {

    int left = term();

    while (input[position] == '+') {

        char op = getNextChar();

        int right = term();

        left += right;

    }

    return left;

}

```


Now, let's break down the key parts of the code:


1. **Global Variables and `getNextChar()`**: We define a global character array `input` to store the input expression and an integer `position` to keep track of the current position in the input string. The `getNextChar()` function is used to consume characters from the input.


2. **`factor()` Function**: This function handles parsing factors, which can be either single digits or expressions enclosed in parentheses. It returns the parsed value.


3. **`term()` Function**: This function handles parsing terms, which are composed of factors separated by `*` operators. It uses the `factor()` function to parse factors and handles the `*` operators.


4. **`expression()` Function**: This function handles parsing expressions, which are composed of terms separated by `+` operators. It uses the `term()` function to parse terms and handles the `+` operators.


5. **`main()` Function**: The main function reads an arithmetic expression from the user and calls the `expression()` function to parse and evaluate it. It then checks if the entire input has been parsed and prints the result or an error message accordingly.


In this example, the code simulates the recursive parsing process by defining functions that correspond to the non-terminals in the grammar. Each function recursively calls other functions to parse and evaluate the input based on the grammar rules.


Comments

Popular posts from this blog

6. Generate a YACC specification to recognize a valid arithmetic expression that uses operators +, – , *,/ and parenthesis.

Below is a YACC specification for recognizing valid arithmetic expressions that involve operators (+, -, *, /) and parentheses. I'll explain each line of the code afterward: ```yacc %{ #include <stdio.h> %} %token NUMBER %left '+' '-' %left '*' '/' %% expression: expression '+' expression            | expression '-' expression            | expression '*' expression            | expression '/' expression            | '(' expression ')'            | NUMBER            ; %% int yylex() {     // Code for tokenizing input and returning tokens } void yyerror(const char *s) {     fprintf(stderr, "Error: %s\n", s); } int main() {     yyparse();     return 0; } ``` Now, let's break down the YACC specification line by line: 1. `%{` ... `%}`: This is the C code section where y...

ktu 2019 Cse Complier programing Lab Syllabus

 1Design and implement a lexical analyzer using C language to recognize all valid tokens  in the input program. The lexical analyzer should ignore redundant spaces, tabs and  newlines. It should also ignore comments. 2. Implement a Lexical Analyzer for a given program using Lex Tool. 3. Write a lex program to display the number of lines, words and characters in an input text. 4. Write a LEX Program to convert the substring abc to ABC from the given input string. 5. Write a lex program to find out the total number of vowels and consonants from the given  input string. 6. Generate a YACC specification to recognize a valid arithmetic expression that uses  operators +, – , *,/ and parenthesis. 7. Generate a YACC specification to recognize a valid identifier which starts with a letter  followed by any number of letters or digits.   8. Implementation of Calculator using LEX and YACC  9. Convert the BNF rules into YACC form and write code to generat...

1, Design and implement a lexical analyzer using C language to recognize all valid tokens in the input program. The lexical analyzer should ignore redundant spaces, tabs and newlines. It should also ignore comments

#include <stdio.h> #include <ctype.h> int main() {     char c;     while ((c = getchar()) != EOF) {         if (isspace(c)) {             // Ignore whitespace, tabs, and newlines             continue;         }         if (c == '/') {             // Check for comments             char nextChar = getchar();             if (nextChar == '/') {                 while ((nextChar = getchar()) != '\n');         ...