CD Practical5
CD Practical5
Practical-5
Theory:
File Content
calc.lex Specifies the lex command specification file that defines the lexical
analysis rules.
calc.yacc Specifies the yacc command grammar file that defines the parsing
rules, and calls the yylex subroutine created by the lex command to
provide input.
lex.yy.c The C language source file that the lex command created for the
lexical analyzer.
cc y.tab.c lex.yy.c Compile and link the two C language source files
Structure:
The file contains the following sections:
%{
code_segment
%}
• Rules section. The rules section defines the rules that parse the input stream.
Keyword Description
%left Identifies tokens that are left-associative with other tokens.
Ex: -
%left '+' '-'
%left '*' '/'
%nonassoc Identifies tokens that are not associative with other tokens.
%right Identifies tokens that are right-associative with other tokens.
%start Identifies a nonterminal name for the start symbol.
%token Identifies the token names that the yacc command accepts. Declares all token
names in the declarations section.
Ex:- %token [<Tag>] Name [Number] [Name [Number]]...
%type Identifies the type of nonterminals. Type-checking is performed when this
construct is present.
%union Identifies the yacc value stack as the union of the various type of values
desired. By default, the values returned are integers. The effect of this construct
is to provide the declaration of YYSTYPE directly from the input.
% start Specifies that the whole input should match stat.
%%
code
Write your grammar rule and action of it.
segment
%%
• Programs section. The programs section contains the following subroutines. Because
these subroutines are included in this file, you do not need to use the yacc library when
processing this file.
Subroutine Description
main The required main program that calls the yyparse subroutine to
start the program.
ex:- main()
{
code_segment
}
yyerror(s) This error-handling subroutine only prints a syntax error message.
yywrap The wrap-up subroutine that returns a value of 1 when the end of
input occurs.
Code:
calc.lex
%{
#include <stdio.h>
#include "y.tab.h"
int c;
%}
%%
"";
[a-z] {c = yytext[0];yylval.a = c - 'a';return(LETTER);}
[0-9] {c = yytext[0];yylval.a = c - '0';return(DIGIT);}
[^a-z0-9\b] {c = yytext[0];return(c);}
%%
calc.yacc
%{
#include<stdio.h>
int regs[26];
int base;
%}
%start list
%union { int a; }
%left '|'
%left '&'
%left '+' '-'
%left '*' '/' '%'
%left UMINUS /*supplies precedence for unary minus */
list: /*empty */
|
list stat '\n'
|
list error '\n'
{
yyerrok;
}
;
stat: expr
{
printf("%d\n",$1);
}
|
LETTER '=' expr
{
regs[$1.a] = $3.a;
}
;
|
number
;
number: DIGIT
{
$$ = $1;
base = ($1.a==0) ? 8 : 10;
} |
number DIGIT
{
$$.a = base * $1.a + $2.a;
}
;
%%
int main()
{
return(yyparse());
}
int yyerror(s)
char *s;
{
fprintf(stderr, "%s\n",s);
}
int yywrap()
{
return(1);
}
Output: