Skip to main content

2. Implement a Lexical Analyzer for a given program using Lex Tool.

 Let's assume we have a simple programming language with keywords `if`, `else`, `while`, and identifiers (variable names) consisting of letters and digits. We want to tokenize a given program written in this language.


Here's the Lex specification file (`lexer.l`) along with explanations:


```lex

%{

#include <stdio.h>

%}


%option noyywrap


%%

if      { printf("IF\n"); }

else    { printf("ELSE\n"); }

while   { printf("WHILE\n"); }

[a-zA-Z][a-zA-Z0-9]* { printf("IDENTIFIER: %s\n", yytext); }

[ \t\n]  ; // Skip whitespace

.        { printf("UNKNOWN CHARACTER: %s\n", yytext); }

%%


int main() {

    yylex();

    return 0;

}

```


Explanation of each section:


- `%{ ... %}`: This section is used for including any necessary header files and declaring global variables or definitions. In this case, we include `stdio.h` for printing messages.


- `%option noyywrap`: This option indicates that the `yywrap` function won't be used. It's commonly used to signal the end of input in Lex programs.


- `%%`: This delimiter separates the Lex rules from the user code.


- `if`, `else`, `while`: These are keywords in our language. For each keyword, we specify a regular expression followed by an action to be taken when a match is found. In this case, we print the corresponding token name.


- `[a-zA-Z][a-zA-Z0-9]*`: This regular expression matches identifiers. It starts with a letter (uppercase or lowercase) and can be followed by letters or digits. When an identifier is matched, we print its value using `yytext`.


- `[ \t\n]`: This regular expression matches whitespace characters (spaces, tabs, newlines). We skip these characters.


- `.`: This regular expression matches any character that didn't match any of the previous patterns. When an unknown character is encountered, we print its value using `yytext`.


- The final section (`main()`) initializes the Lexical Analyzer using `yylex()`.


To compile and run the program:


1. Save the Lex specification in a file named `lexer.l`.

2. Open a terminal and navigate to the directory containing `lexer.l`.

3. Run the following commands:

   - `lex lexer.l` (compiles the Lex specification)

   - `gcc lex.yy.c -o lexer -ll` (compiles the Lex-generated code)

   - `./lexer` (runs the program)


Now, you can provide input text (your program) to the compiled lexer, and it will tokenize the input and display the corresponding tokens.


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...

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');         ...

17. Write a program to perform constant propagation.

Sure, I can provide you with a basic example of a constant propagation program along with explanations for each line. Please note that this example is simplified and might not cover all possible cases of constant propagation. ```c #include <stdio.h> #include <stdbool.h> // Structure to represent an assignment statement struct Assignment {     char variable;     int value;     bool isConstant; }; int main() {     // Example assignments (variable, value, isConstant)     struct Assignment assignments[] = {         {'a', 10, true},         {'b', 20, true},         {'c', 0, true},         {'d', 30, false},         {'e', 0, false}     };     int numAssignments = sizeof(assignments) / sizeof(assignments[0]);     // Perform constant propagation     for (int i = 0; i < numAssignments; i++) { ...