CD Yacc AndLex
CD Yacc AndLex
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.
%%
%%
int yywrap() {
return 1;
}
%}
%union {
int i;
char *s;
}
%%
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;
}
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:
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.
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.
%%
%%
int yywrap() {
return 1;
}
%}
%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;
}
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:
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.
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.
%%
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;
}
%}
%%
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;
}
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:
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.
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.
%%
%%
int yywrap() {
return 1;
}
%union {
int 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;
}
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:
This is a minimal example of how to implement a basic calculator using Lex for tokenization
and Yacc for parsing arithmetic expressions.
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.
%%
%%
int yywrap() {
return 1;
}
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;
}
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:
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).
%%
%%
int yywrap() {
return 1;
}
%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;
}
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:
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.