Why is there a syntax error on the program when v is located immediately after s? (Lex Yacc) - yacc

Lex Code
...
%option noyywrap
%{
#include<stdio.h>
#include"y.tab.h"
%}
%%
I|you|we|they|he|she|it return SUBJECT;
will return AUX1;
did return AUX2;
not return NOT;
eat|drink|run|play return VERB1;
ate|drank|ran|played return VERB2;
\. return DOT;
\? return QUE;
%%
...
Yacc code
...
%{
#include<stdio.h>
#include<stdlib.h>
void yyerror(char *msg);
%}
%token SUBJECT VERB1 DOT QUE VERB2 AUX1 AUX2 NOT
%%
sentence:
past DOT {printf(" Sentence Approved "); exit(0);}
| pastneg DOT {printf(" Sentence Approved "); exit(0);}
| pastint QUE {printf(" Sentence Approved "); exit(0);}
| fut DOT {printf(" Sentence Approved "); exit(0);}
| futneg DOT {printf(" Sentence Approved "); exit(0);}
| futint QUE {printf(" Sentence Approved "); exit(0);}
;
present:
s v {printf(" Simple Present Tense");}
;
past:
s p {printf(" Simple Past Tense");}
;
pastneg:
s x2 neg v {printf(" Negative Simple Past Tense");}
;
pastint:
x2 present {printf(" Interrogative Simple Past Tense");}
;
fut:
s x1 v {printf(" Simple Future Tense");}
;
futneg:
s x1 neg v {printf(" Negative Simple Future Tense");}
;
futint:
x1 present {printf(" Interrogative Simple Future Tense");}
;
s:
SUBJECT {printf("Subject");}
;
p:
VERB2 {printf("Verb2");}
;
x1:
AUX1 {printf("will");}
;
x2:
AUX2 {printf("did");}
;
v:
VERB1 {printf("Verb");}
;
neg:
NOT {printf("Negative");}
;
%%
void yyerror(char *msg){
fprintf(stderr, "%s\n", msg);
exit(1);
}
int main()
{
yyparse();
return 0;
}
There seems to be a syntax error whenever I try to run the pastint and futint. The present is also an error since VERB1 (v) is followed immediately after SUBJECT (s). I was expecting that if I input "Will he eat?" or "Did you run?" the output would be "Auxiliary Subject Verb1 Simple Past/Future Tense Sentence Accepted". But the output that I got at the moment is "Auxiliary subject Syntax error". Can anyone help me solve this problem?

Related

Calculator in lex and yacc

I am trying to create a calculator by using lex and yacc. However I can not understand how can I give operator precedence to this program? I could not find any information about it. Which code do I need to add to my project to calculate correctly?
Yacc file is:
%{
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int yylex();
void yyerror(const char *s);
%}
%token INTEGER
%left '*' '/'
%left '+' '-'
%%
program:
program line | line
line:
expr ';' { printf("%d\n",$1); } ; | '\n'
expr:
expr '+' term { $$ = $1 + $3; }
| expr '-' term { $$ = $1 - $3; }
| expr '*' term { $$ = $1 * $3; }
| expr '/' term { $$ = $1 / $3; }
| expr '%' term { $$ = $1 % $3; }
| expr '^' term { $$ = $1 ; }
| term { $$ = $1; }
term:
INTEGER { $$ = $1; }
%%
void yyerror(const char *s) { fprintf(stderr,"%s\n",s); return ; }
int main(void) { /*yydebug=1;*/ yyparse(); return 0; }
Lex file is:
%{
#include <stdlib.h>
#include <stdio.h>
void yyerror(char*);
extern int yylval;
#include "calc.tab.h"
#include<time.h>
%}
%%
[ \t]+ ; //skip whitespace
[0-9]+ {yylval = atoi(yytext); return INTEGER;}
[-+*/%^] {return *yytext;}
\n {return *yytext;}
; {return *yytext;}
. {char msg[25]; sprintf(msg,"%s <%s>","invalid character",yytext); yyerror(msg);}
%left '*' '/'
%left '+' '-'
Precedence declarations are specified in the order from lowest precedence to highest. So in the above code you give * and / the lowest precedence level and + and - the highest. That's the opposite order of what you want, so you'll need to switch the order of these two lines. You'll also want to add the operators % and ^, which are currently part of your grammar, but not your precedence annotations.
With those changes, you'll now have specified the precedence you want, but it won't take effect yet. Why not? Because precedence annotations are used to resolve ambiguities, but your grammar isn't actually ambiguous.
The way you've written the grammar, with only the left operand of all operators being expr and the right operand being term, there's only one way to derive an expression like 2+4*2, namely by deriving 2+4 from expr and 2 from term (because deriving 4*2 from term would be impossible since term can only match a single number). So your grammar treats all operators as left-associative and having the same precedence and your precedence annotations aren't considered at all.
In order for the precedence annotations to be considered, you'll have to change your grammar, so that both operands of the operators are expr (e.g. expr '+' expr instead of expr '+' term). Written like that an expression like 2+4*2 could either be derived by deriving 2+4 from expr as the left operand and 2 from expr as the right operand or 2 as the left and 4*2 as the right and this ambiguity will be resolved using your precedence annotations.

how to fix integer out of range error :$3 error in YACC

I am developing a calculator using YACC and I receive this error :
Integer out of rang $3;
I have just now started learning yacc and can't rectify the error I can see the question already but no one has answered
%token NUMBER
%%
expr :expr '+'{$$ = $1 + $3;}
%%
#include<stdio.h>
#include "lex.yy.c"
yylex()
{
int c;
c=getchar();
if(isdigit(c))
{
yylval=c-'0';
return NUMBER;
}
return c;
}
int main()
{
yyparse();
return 1;
}
int yyerror(){
return 1;}
$3 refers to the 3rd term on the right side of the rule. In
expr :expr '+'{$$ = $1 + $3;}
there are only 2 terms on the right side of the production...

Warning: 2 shift/reduce conflicts [-Wconflicts-sr] err

%{
#include<stdio.h>
#include<stdlib.h>
int regs[30];
%}
%token NUMBER LETTER
%left PLUS MINUS
%left MULT DIV
%%
prog: prog st | ; //when I remove this line the error goes
st : E {printf("ans %d", $1);}| LETTER '=' E {regs[$1] = $3; printf("variable contains %d",regs[$1]);};
E : E PLUS E{$$ = $1 + $3;} //addition
| E MINUS E{$$ = $1 - $3 ;} //subtraction
| MINUS E{$$ = -$2;}
| E MULT E{$$ = $1 * $3 ;}
| E DIV E { if($3)$$= $1 / $3; else yyerror("Divide by 0");}
/*|LBRACE E RBRACE{$$= $2;}
| RBRACE E LBRACE{yyerror("Wrong expression");} */
| NUMBER {$$ = $1;}
| LETTER {$$ = regs[$1];}
;
%%
int main(void)
{
printf("Enter Expression: ");
yyparse();
return 0;
}
int yyerror(char *msg)
{
printf("%s", msg);// printing error
exit(0);
}
I am not able to resolve the conflicts. Also I am getting a segmentation fault when I run it with some edits. I am using yacc and lex for the same.
The two shift-reduce conflicts are the result of the fact that you don't require any explicit separator between statements. Because of that, a = b - 3 could be interpreted as one statement or as two (a = b; - 3). The second interpretation may not seem very natural to you but it is easily derived by the grammar.
In addition, your use of unary minus leads to an incorrect parse of -2/3 as -(2/3) instead of (-2)/3. (You may or may not find this serious, since it has few semantic consequences with these particular operators.) This particular issue and a correct resolution is discussed in the bison manual, and in many many other internet resources.
Both of these explanations are made a bit more visible if you use the -v command line option to bison to produce a description of the parser. See Understanding your parser (again, in the bison manual).

Lex & Yacc - Grammar rules

I am trying to learn lex and yacc.
I am struggling to understand how to do the grammar rules.
My file has already been defined like:
fd 3x00
bk 100
setc 100
int xy3 fd 10 rt 90
rt
My output with the printf and printing to a file went something like this:
Keyword: fd
Illegal: 3x00
Keyword: bk
Keyword: setc
Number: 100
Keyword: int
Id: xy3
Keyword: fd
Number: 10
Keyword: rt
Number: 90
Here is my lex file - im only going to show part of it to keep this post as small as possible
fd {return FD; }
[0-9]+[a-z]+[0-9]+ {} // this is the illegal entry 3x00
[\r\t\n]+ {}
bk {return BK;}
setc {return SETC;}
[-+]?[0-9]+ {yyval.ival = atoi(yytext); return NUMBER;}
int {fprintf(yyout, "%s\n", yytext);}
xy3 {fprintf(yyout, "%s\n", yytext);}
fd[0-9]+ {fprintf(yyout, "%s\n", yytext);}
%%
Here is my yacc file. It is not complete since i dont know how to finish it.
%{
#include <ctype.h>
#include <stdio.h>
%}
%token NUMBER
%token ID
%token FD
%token BK
%token SETC
%token KEYWORD
%%
%%
main()
{
yyparse()
}
I am not sure how i would write the grammar rules for these.
Can i make my own name for the expression?
can anyone help me with one example so i can see how to finish it?
The rules should be like this:
statement: command arg {printf("Keyword: %s\n", $1);};
command: KEYWORD {$$ = $1;}
|FD {$$ = $1;}
|BK {$$ = $1;};
arg: NUMBER {printf("Number: %s\n", $1);}
|ID {printf("Id: %s\n", $1);};
That means, you should define the syntactical rules in this way. Separate alternative definitions by |, and write the desired actions in a { } block for each rule. Finish each rule with a ;. When you refer to the the tokens, use $n where n is the position of the token in the rule. The rule header can be referred to using $$.

Why am I getting conflicts: 1 shift/reduce

I'm new to bison and I'm getting a "conflicts: 1 shift/reduce" error. Can anyone shed some light on this?
Here's the y file.
test.y:
%{
#include <stdio.h>
#include <string.h>
#define YYERROR_VERBOSE
#define YYDEBUG 1
void yyerror(const char *str);
int yywrap();
%}
%union
{
int integer;
char *string;
}
%token <string> VAR_LOCAL
%token <integer> LIT_NUMBER
%token <string> LIT_STRING
%token WS_LINEBRK
//%token SYMB_EQL
%token SYMB_PLUS
%token SYMB_MINUS
%token SYMB_MUL
%token SYMB_DIV
%%
/*
// Sample input
num = 10
str = "this is a string"
*/
inputs: /* empty token */
| literal
| variable
| inputs stmt WS_LINEBRK
;
stmt: variable "=" exps
;
exps: variable op literal
| variable op variable
| literal op literal
| literal op variable
;
op: SYMB_PLUS | SYMB_MINUS | SYMB_MUL | SYMB_DIV ;
variable: VAR_LOCAL
{
printf("variable: %s\n", $1);
}
;
literal:
number | string
;
string: LIT_STRING
{
printf("word: %s\n", $1);
}
;
number: LIT_NUMBER
{
printf("number: %d\n", $1);
}
;
%%
void yyerror(const char *str)
{
fprintf(stderr,"error: %s\n",str);
}
int yywrap()
{
return 1;
}
main()
{
yyparse();
}
Here's the lex file
test.l:
%{
#include <stdio.h>
#include <stdlib.h>
#include "y.tab.h"
int line_no = 0;
%}
%%
[a-z][a-zA-Z0-9]* {
// local variable
yylval.string=strdup(yytext);
return VAR_LOCAL;
}
[0-9]+ {
//number literal
yylval.integer=atoi(yytext);
return LIT_NUMBER;
}
= return SYMB_EQL;
\+ return SYMB_PLUS;
\- return SYMB_MINUS;
\* return SYMB_MUL;
\/ return SYMB_DIV;
\"[-+\!\.a-zA-Z0-9' ]+\" {
// word literal
yylval.string=strdup(yytext);
return LIT_STRING;
}
\n {
// line break
printf("\n");
return WS_LINEBRK;
}
[ \t]+ /* ignore whitespace */;
%%
bison -r test.y will write a file test.output with a detailed description of the generated state machine that allows you to see what's going on - such as the state where the shift/reduce conflict occurs.
In your case, the problem is in the start state (corresponding to your start nonterminal, inputs). Say the first token is VAR_LOCAL. There's two things your parser could do:
It could match the variable case.
It could also match the inputs stmt WS_LINEBRK case: inputs matches the empty string (first line), and stmt matches variable "=" exps.
With the one token of lookahead that bison parsers use, there's no way to tell. You need to change your grammar to get rid of this case.
To fix the grammar, as Fabian has suggested, move the variable and literal to the end of exps from inputs
inputs:
| variable
| literal
exps:
...
| variable
| literal
That allows x= y,x="aliteral" syntax.
To allow for empty input lines, change the /* empty token */ rule to WS_LINEBREAK:
inputs: WS_LINEBRK
| stmt WS_LINEBRK
| inputs stmt WS_LINEBRK
;
On another note, since the scanner still looks for the SYMB_ EQUAL ; but the parser no longer defines it (its commented out), something needs to be done in order to compile. One option is to uncomment the %token definition and use SYMB_ EQUAL instead of the literal "=" in the parser .y file.