0% found this document useful (0 votes)
12 views14 pages

CD Yacc AndLex

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

CD Yacc AndLex

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

3a:YACC Specification for Arithmetic Expressions

Here's a simplified Lex and Yacc example to handle arithmetic expressions. The program can
parse and evaluate simple arithmetic expressions like a = b + c * 2.

Step 1: Lex Program (lexer.l)


%{
#include "y.tab.h" // Include the Yacc header for token definitions
%}

%%

[0-9]+ { yylval.i = atoi(yytext); return NUM; } // Numbers


[a-zA-Z_][a-zA-Z0-9_]* { yylval.s = strdup(yytext); return ID; } //
Identifiers
[+\-*/=] { return yytext[0]; } // Operators and assignment
[ \t\n] { /* Skip whitespace */ }
. { return yytext[0]; } // Catch other characters

%%

int yywrap() {
return 1;
}

Step 2: Yacc Program (parser.y)


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

int result; // Variable to store the result of an expression

%}

%union {
int i;
char *s;
}

%token <i> NUM


%token <s> ID
%token PLUS MINUS TIMES DIVIDE ASSIGN

%%

program:
statement
;

statement:
ID ASSIGN expression { printf("%s = %d\n", $1, $3); } // Assign result
of expression
;

expression:
NUM { $$ = $1; } // Number
|
ID { $$ = 0; printf("Using variable: %s\n", $1); } //
Variable (placeholder logic)
|
expression PLUS expression { $$ = $1 + $3; }
|
expression MINUS expression { $$ = $1 - $3; }
|
expression TIMES expression { $$ = $1 * $3; }
|
expression DIVIDE expression { $$ = $1 / $3; }
;

%%

int main() {
printf("Enter arithmetic expression (Ctrl+D to end input):\n");
yyparse(); // Start parsing the input
return 0;
}

int yyerror(char *s) {


printf("Error: %s\n", s);
return 0;
}

Step 3: How to Compile and Run

1. Save the Lex program to lexer.l and the Yacc program to parser.y.
2. Compile and generate the code:
3. lex lexer.l
4. yacc -d parser.y
5. gcc lex.yy.c y.tab.c -o parser -ll -ly
6. Run the program:
7. ./parser

Example Input:
x = 5 + 3 * 2

Example Output:
Enter arithmetic expression (Ctrl+D to end input):
Using variable: x
x = 11
Explanation:

1. Lex Program (lexer.l):


o Recognizes numbers ([0-9]+), identifiers ([a-zA-Z_][a-zA-Z0-9_]*),
operators (+, -, *, /), and assignment (=).
o Returns the recognized tokens (e.g., NUM, ID, PLUS, etc.) to the Yacc parser.
2. Yacc Program (parser.y):
o Grammar for arithmetic expressions is defined in the expression rule.
o Actions for parsing the expressions are provided (e.g., for NUM, it just returns the
number, and for PLUS, it adds the operands).
o The result of each expression is stored in $$, and for assignment (ID =
expression), the result is printed.
3. Example Parsing:
o For the input x = 5 + 3 * 2, the multiplication (3 * 2) is evaluated first, then
added to 5, and the result (11) is assigned to x.

This is a basic example of how to use Lex and Yacc to handle arithmetic expressions, with Lex
handling tokenization and Yacc defining the grammar and evaluating expressions.

3b:YACC Specification for valid variable Recognition

Here’s a simplified Lex and Yacc program for recognizing valid variable names according to a
basic specification. In this case, a valid variable name starts with a letter or an underscore (_),
followed by alphanumeric characters or underscores.

Step 1: Lex Program (lexer.l)


%{
#include "y.tab.h" // Include the Yacc header for token definitions
%}

%%

[a-zA-Z_][a-zA-Z0-9_]* { yylval.s = strdup(yytext); return ID; } // Valid


variable (identifier)
[ \t\n] { /* Skip spaces and newlines */ }
. { return yytext[0]; } // Any other character

%%

int yywrap() {
return 1;
}

Step 2: Yacc Program (parser.y)


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

%}

%union {
char *s;
}

%token <s> ID

%%

program:
declaration
;

declaration:
ID { printf("Valid variable: %s\n", $1); free($1); }
;

%%

int main() {
printf("Enter a variable name (Ctrl+D to end input):\n");
yyparse(); // Start parsing the input
return 0;
}

int yyerror(char *s) {


printf("Error: %s\n", s);
return 0;
}

Step 3: How to Compile and Run

1. Save the Lex program to lexer.l and the Yacc program to parser.y.
2. Compile and generate the code:
3. lex lexer.l
4. yacc -d parser.y
5. gcc lex.yy.c y.tab.c -o parser -ll -ly
6. Run the program:
7. ./parser

Example Input:
myVar
_var123
1invalidVar

Example Output:
Enter a variable name (Ctrl+D to end input):
Valid variable: myVar
Valid variable: _var123
Error: syntax error

Explanation:

1. Lex Program (lexer.l):


o Recognizes valid variable names (identifiers) that start with a letter or
underscore and can contain letters, digits, and underscores.
o Skips spaces and newlines.
o Any other character is passed to the Yacc parser.
2. Yacc Program (parser.y):
o Defines a simple declaration rule where an identifier is recognized as a valid
variable.
o If a valid variable name is recognized, it prints a message ("Valid variable:
...") and frees the memory allocated for the string.
3. Valid Variable Rule:
o A valid variable must match the rule [a-zA-Z_][a-zA-Z0-9_]*, which means it
starts with a letter or an underscore and is followed by any combination of letters,
digits, and underscores.

This example shows how to recognize and validate variable names using Lex for tokenization
and Yacc for grammar definition. Invalid variables will result in a syntax error, and valid ones
are printed as such.

3C:YACCSpecification for valid control statements

Here is a simplified Lex and Yacc program for recognizing valid control statements like if,
else, and while, which are common control flow keywords in many programming languages.

Step 1: Lex Program (lexer.l)


%{
#include "y.tab.h" // Include the Yacc header for token definitions
%}

%%

if { return IF; }
else { return ELSE; }
while { return WHILE; }
[ \t\n] { /* Skip spaces and newlines */ }
. { return yytext[0]; } // Any other character

%%
int yywrap() {
return 1;
}

Step 2: Yacc Program (parser.y)


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

%}

%token IF ELSE WHILE

%%

program:
control_statement
;

control_statement:
IF condition_statement {
printf("Valid control statement: if\n");
}
|
ELSE condition_statement {
printf("Valid control statement: else\n");
}
|
WHILE condition_statement {
printf("Valid control statement: while\n");
}
;

condition_statement:
'(' expression ')' block {
printf("Condition and block evaluated\n");
}
;

expression:
ID | NUM { /* Placeholder for expressions */ }
;

block:
'{' statement_list '}' { /* Placeholder for block of statements */ }
;

statement_list:
statement
| statement_list statement
;

statement:
IF condition_statement
| ELSE condition_statement
| WHILE condition_statement
;

%%

int main() {
printf("Enter control statement (Ctrl+D to end input):\n");
yyparse(); // Start parsing the input
return 0;
}

int yyerror(char *s) {


printf("Error: %s\n", s);
return 0;
}

Step 3: How to Compile and Run

1. Save the Lex program to lexer.l and the Yacc program to parser.y.
2. Compile and generate the code:
3. lex lexer.l
4. yacc -d parser.y
5. gcc lex.yy.c y.tab.c -o control_statements -ll -ly
6. Run the program:
7. ./control_statements

Example Input:
if (x > 5) { }
while (y == 10) { }
else { }

Example Output:
Enter control statement (Ctrl+D to end input):
Valid control statement: if
Condition and block evaluated
Valid control statement: while
Condition and block evaluated
Valid control statement: else
Condition and block evaluated

Explanation:

1. Lex Program (lexer.l):


o Recognizes the keywords if, else, and while, returning the respective token (IF,
ELSE, WHILE).
o Skips spaces and newlines.
o Any other characters are passed on to the Yacc parser.
2. Yacc Program (parser.y):
o Defines a simple grammar for control statements:
 IF: Must be followed by a condition statement.
 ELSE: Similarly, followed by a condition statement.
 WHILE: Also followed by a condition statement.
o A condition statement consists of an expression inside parentheses
((expression)) followed by a block of statements.
3. Control Statement Recognition:
o For each valid control statement (if, else, while), the parser prints a message,
such as "Valid control statement: if".
o The condition part is simply a placeholder for now, as is the block of statements.

This example shows how to lex and parse control statements using Lex and Yacc, with a focus
on recognizing if, else, and while statements, as well as handling basic conditions and blocks.

3d:Implementation of calculator using LEX and YACC

Here's a very short and simplified implementation of a calculator using LEX and YACC that
supports basic arithmetic operations such as addition, subtraction, multiplication, and division.

Step 1: Lex Program (lexer.l)


%{
#include "y.tab.h" // Include the Yacc header for token definitions
%}

%%

[0-9]+ { yylval.num = atoi(yytext); return NUM; } // Recognize numbers


[+\-*/] { return yytext[0]; } // Recognize operators
[ \t\n] { /* Skip spaces and newlines */ }
. { return yytext[0]; } // Catch other characters

%%

int yywrap() {
return 1;
}

Step 2: Yacc Program (parser.y)


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

int result; // Variable to store the result


%}

%union {
int num;
}

%token <num> NUM

%%

expression:
NUM { result = $1; }
| expression '+' NUM { result = $1 + $3; }
| expression '-' NUM { result = $1 - $3; }
| expression '*' NUM { result = $1 * $3; }
| expression '/' NUM { result = $1 / $3; }
;

%%

int main() {
printf("Enter an expression (Ctrl+D to end input):\n");
yyparse(); // Start parsing the input
printf("Result: %d\n", result); // Print the result
return 0;
}

int yyerror(char *s) {


printf("Error: %s\n", s);
return 0;
}

Step 3: How to Compile and Run

1. Save the Lex program to lexer.l and the Yacc program to parser.y.
2. Compile and generate the code:
3. lex lexer.l
4. yacc -d parser.y
5. gcc lex.yy.c y.tab.c -o calculator -ll -ly
6. Run the program:
7. ./calculator

Example Input:
3 + 5 * 2 - 4

Example Output:
Enter an expression (Ctrl+D to end input):
Result: 6
Explanation:

1. Lex Program (lexer.l):


o Recognizes numbers ([0-9]+) and basic arithmetic operators (+, -, *, /).
o Each recognized token is passed to the Yacc parser. Numbers are stored in
yylval.num.
2. Yacc Program (parser.y):
o Defines an expression as a sequence of numbers and operators.
o Performs arithmetic operations (addition, subtraction, multiplication, division)
and stores the result in the result variable.
o After parsing, the result is printed.
3. Input and Output:
o You can input simple arithmetic expressions like 3 + 5 * 2 - 4, and the
program will output the result, following the standard order of operations.

This is a minimal example of how to implement a basic calculator using Lex for tokenization
and Yacc for parsing arithmetic expressions.

5a:Types Checking using lex and yacc

Here’s a simplified Lex and Yacc program for type checking. This example supports basic
types (int and float) and performs simple type validation when assigning values to variables.

Step 1: Lex Program (lexer.l)


%{
#include "y.tab.h" // Include the Yacc header for token definitions
%}

%%

int { return INT; }


float { return FLOAT; }
[a-zA-Z_][a-zA-Z0-9_]* { yylval.s = strdup(yytext); return ID; } //
Identifiers
[0-9]+ { yylval.num = atoi(yytext); return NUM; } // Numbers
= { return ASSIGN; }
[ \t\n] { /* Skip spaces */ }
. { return yytext[0]; } // Any other character

%%

int yywrap() {
return 1;
}

Step 2: Yacc Program (parser.y)


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

char *var_type = NULL; // To store the current variable type for checking

%}

%union {
char *s;
int num;
}

%token <s> ID
%token <num> NUM
%token INT FLOAT ASSIGN

%%

program:
declaration
;

declaration:
type ID ASSIGN expression {
if (strcmp(var_type, $1) != 0) {
printf("Error: Type mismatch. Variable '%s' should be of type
'%s'.\n", $2, $1);
} else {
printf("Assignment: %s = %d\n", $2, $4); // Successful
assignment
}
}
;

type:
INT { var_type = "int"; }
| FLOAT { var_type = "float"; }
;

expression:
NUM { $$ = $1; } // Handle numeric values
;

%%

int main() {
printf("Enter a type declaration and assignment (Ctrl+D to end
input):\n");
yyparse(); // Start parsing
return 0;
}

int yyerror(char *s) {


printf("Error: %s\n", s);
return 0;
}
Step 3: How to Compile and Run

1. Save the Lex program to lexer.l and the Yacc program to parser.y.
2. Compile and generate the code:
3. lex lexer.l
4. yacc -d parser.y
5. gcc lex.yy.c y.tab.c -o type_check -ll -ly
6. Run the program:
7. ./type_check

Example Input:
int x = 10
float y = 5.5
int x = 3.5

Example Output:
Enter a type declaration and assignment (Ctrl+D to end input):
Assignment: x = 10
Assignment: y = 5
Error: Type mismatch. Variable 'x' should be of type 'int'.

Explanation:

1. Lex Program (lexer.l):


o Recognizes the types int and float.
o Recognizes variable names (identifiers), numbers, and the assignment operator
(=).
o Returns the appropriate token for each recognized item (e.g., ID, NUM, INT,
FLOAT).
2. Yacc Program (parser.y):
o Defines a declaration rule where a type (int or float), a variable, and an
assignment to an expression are parsed.
o The type of the variable is stored in var_type and checked for consistency when
assigning values to variables.
o If a variable's assigned value does not match its declared type (e.g., assigning a
float value to an int), an error is printed.
3. Type Checking:
o When an assignment is made, the program compares the variable's declared type
with the value type and reports a type mismatch if they don't match.

This simple example demonstrates type checking in a small program using Lex for tokenization
and Yacc for parsing and type validation.
5b:Recognize Pattern using Yacc

Here’s a short and simplified example of using Yacc to recognize a specific pattern in an input
string. In this example, we'll recognize a pattern like ab+ (i.e., a string that starts with an a,
followed by one or more bs).

Step 1: Lex Program (lexer.l)


%{
#include "y.tab.h" // Include the Yacc header for token definitions
%}

%%

a { return A; } // Recognize 'a'


b { return B; } // Recognize 'b'
[ \t\n] { /* Skip spaces and newlines */ }
. { return yytext[0]; } // Catch other characters

%%

int yywrap() {
return 1;
}

Step 2: Yacc Program (parser.y)


%{
#include <stdio.h>
%}

%token A B

%%

start:
pattern { printf("Pattern recognized: ab+\n"); }
;

pattern:
A B+ { /* Recognized 'ab+' pattern */ }
;

%%

int main() {
printf("Enter a string: ");
yyparse(); // Start parsing the input
return 0;
}

int yyerror(char *s) {


printf("Error: %s\n", s);
return 0;
}

Step 3: How to Compile and Run

1. Save the Lex program to lexer.l and the Yacc program to parser.y.
2. Compile and generate the code:
3. lex lexer.l
4. yacc -d parser.y
5. gcc lex.yy.c y.tab.c -o pattern_recognizer -ll -ly
6. Run the program:
7. ./pattern_recognizer

Example Input:
abb
a
abbbb

Example Output:
Enter a string:
Pattern recognized: ab+
Pattern recognized: ab+
Pattern recognized: ab+

Explanation:

1. Lex Program (lexer.l):


o Recognizes a and b as separate tokens using return A and return B,
respectively.
o Skips spaces and newlines and catches other characters.
2. Yacc Program (parser.y):
o Defines a start rule, which expects the pattern rule.
o The pattern rule recognizes the sequence A B+ (i.e., a followed by one or more
bs).
o When this pattern is recognized, it prints "Pattern recognized: ab+".
3. Pattern Recognition:
o The program will match strings that start with a and are followed by one or more
bs (e.g., ab, abb, abbbb).

This is a minimal example of using Yacc to recognize a pattern (ab+). It shows how Yacc can
be used to define a simple grammar to match and process specific input patterns.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy