I'm working on vmWare linux ubuntu on a bison-dlex project, and I have an error in my bison file which I can't get over. In my "line' definition I have " logExp '\n' " definition, but for some reason it never gets there even though it does recognize the expression as logExp.
line:
expr '\n' { printf("\nExpression = %d\n", $1); }
| logExp '\n' { printf("\nNEVER GETS HERE!!\n"); } //ERROR
;
logExp:
expr AND expr { $$ = 0 ; printf("\n$1=%d, $3=%d\n",$1,$3); } //PRINTS GOOD
| AND { }
;
input:
5&&6
output:
$1=5, $3=6
Error: parse error
If it recognizes the logExp, how come it doesn't recognize the line above??
..HELP ?
Related
I am studying compilers and studying Lex and Yacc. I write a LexYacc code as my teacher shows:
here is exp.l:
/*%option outfile="scanner.cpp"*/
%{
/*#include "exp.tab.h"*/
#include "y.tab.h"
extern int yylval;
%}
%%
0|[1-9][0-9]* { yylval = atoi(yytext); return INTEGER; }
[+*()\n] { return yytext[0]; }
. { /* do nothing */ }
%%
and this is exp.y:
/*
%output "parser.cpp"
%skeleton "lalr1.cc"
*/
%{
#include <stdio.h>
%}
%token INTEGER
%left '+'
%left '*'
%%
input : /* empty string */
| input line
;
line : '\n'
| exp '\n' { printf ("\t%d\n", $1); }
| error '\n'
;
exp : INTEGER { $$ = $1; }
| exp '+' exp { $$ = $1 + $3; }
| exp '*' exp { $$ = $1 * $3; }
| '(' exp ')' { $$ = $2; } ;
%%
main () {
yyparse ();
}
yyerror (char *s) {
printf ("%s\n", s);
}
and I use linux command to run it:
flex exp.l
bison -d exp.y
gcc exp.tab.c lex.yy.c -o exp -lfl
and it shows this:
exp.tab.c: In function ‘yyparse’:
exp.tab.c:1217:16: warning: implicit declaration of function ‘yylex’ [-Wimplicit-function-declaration]
1217 | yychar = yylex ();
|
exp.tab.c:1374:7: warning: implicit declaration of function ‘yyerror’; did you mean ‘yyerrok’? [-Wimplicit-function-declaration]
1374 | yyerror (YY_("syntax error"));
|
| yyerrok
exp.y: At top level:
exp.y:28:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
28 | main () {
|
exp.y:33:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
33 | yyerror (char *s) {
|
exp.l:4:10: fatal error: y.tab.h: No such file or directory
4 | #include "y.tab.h"
|
compilation terminated.
The whole program is mainly a calculator to calculate addition and multiplication.
I don't know what happened and hope someone can help me.
I am trying to create a parser-generator using flex/bison. This is my partial parser.y code:
func_definition : type_specifier ID LPAREN parameter_list RPAREN compound_statement
{
$$=new Symbol_info();
$$->code+="PROC:"+ $2->symbol+"\n";
if($2->symbol!="main")
{
$$->code+="PUSH AX\n";
$$->code+="PUSH BX\n";
$$->code+="PUSH CX\n";
$$->code+="PUSH DX\n";
}
$$->code += $6->code ;
if($2->symbol!="main") {
$$->code+="POP DX\n";
$$->code+="POP CX\n";
$$->code+="POP BX\n";
$$->code+="POP AX\n";
}
fprintf(parseLog, "GRAMMER RULE: func_definition -> type_specifier ID LPAREN parameter_list RPAREN compound_statement \n");
}
;
And this is my partial lex.l code.
{id} {
Symbol_info *s= new Symbol_info(yytext, "ID");
yylval = (YYSTYPE)s;
return ID;
}
And this is my partial symbol_table.h code
class SymbolInfo{
string type;
string symbol;
public:
string code;
SymbolInfo *next;
SymbolInfo(){
symbol="";
type="";
code="";
}
SymbolInfo(string symbol, string type){
this->symbol=symbol;
this->type=type;
code="";
}
SymbolInfo(char *symbol, char *type){
this->symbol=string(symbol);
this->type= string(type);
code="";
}
SymbolInfo(const SymbolInfo *sym){
symbol=sym->symbol;
type=sym->type;
code=sym->code;
}
So, when I create a program, I get a SIGSEGV segmentation fault. (Address boundary error). It appears that I get that error when I try to access the yylval returned to me by the lex function.
I tried to run this code on an Ubuntu 64-bit instance (Ubuntu 17.10). I don't know why but the same code runs fine on a 32 bit system (Ubuntu 14.10).
Maybe it's because of the large Integer sizes. Here is the code if you're interested.
I'm using Rcpp and RInside to run some commands into R.
I've made a personal GUI (in Qt) which sends commands, and I would like to recover the result in std::string format.
Example :
$ 1 + 1
The result is :
[1] 2
And I want to have this string :
"[1] 2"
I already check string cast with "as" and "as_string", but the cast is invalid cause of intern return type in R.
Is it possible to read R console output or something else ?
EDIT:
void RppMainWindow::runLineOnScriptCursor() {
std::string line = script->getCodeEditor()->lineOnCursor();
if ( line.empty() || line == INVALID ) {
return;
}
RCommand cmd (script->getConsoleViewer(), r);
cmd.execute(line);
}
void RCommand::execute(std::string commande) {
std::string res = executeOnR(commande);
viewer->addEntry(commande, res);
}
void ConsoleViewer::addEntry(std::string command, std::string result) {
this->moveCursor(QTextCursor::End);
QTextCharFormat format;
format.setFontWeight(QFont::DemiBold);
format.setForeground(QBrush(QColor("red")));
this->mergeCurrentCharFormat(format);
std::string tmp = "> " + command + "\n";
this->insertPlainText(QString(tmp.c_str()));
this->moveCursor(QTextCursor::End);
format.setFontWeight(QFont::Normal);
format.setForeground(QBrush(QColor("blue")));
this->mergeCurrentCharFormat(format);
if ( ! result.empty() ) {
result += "\n";
}
this->insertPlainText(QString(result.c_str()));
}
ConsoleViewer allow to display a basic R console like this
$ R command
return if needed
If you want
"[1] 2"
you need to setup a formatting routine at your end that receives the 2 from RInside and prepends [1] (and ditto for the other lines). This is just what print() does in R:
edd#max:~$ R --slave -e 'print(1+1)'
[1] 2
edd#max:~$ R --slave -e 'cat(1+1, "\n")'
2
edd#max:~$
I actually prefer cat() on my results but print() can be emulated too.
Write a parser (both Yacc and Lex files) that uses the following productions and actions:
S -> cSS {print “x”}
S -> a {print “y”}
S -> b {print “z”}
Indicate the string that it will print when the input is cacba.
I am getting this error: when I give input to it, it says valid input and also says syntax error.
My Scanner Code is this
%{
#include "prac.h"
%}
%%
[c] {return C; }
[a] {return A; }
[b] {return B; }
[ \t] ;
\n { return 0; }
. { return yytext[0]; }
%%
int yywrap(void) {
return 1;
}
And my yacc code is this:
%{
#include <stdio.h>
%}
%token A B C
%%
statement: S {printf("Valid Input"); }
;
S: C S S {printf("Print x\n");}
| A {printf("Print y\n");}
| B {printf("Print z\n");}
;
%%
int main()
{
return yyparse();
}
yyerror(char *s)
{
printf("\n%s\n",s);
printf("Invalid Input");
fprintf(stderr,"At line %d %s ",s,yylineno);
}
How can I fix this?
(Comments converted to an answer)
#ChrisDodd wrote:
Best guess -- you're running on windows, so you're getting a \r (carriage return) character before the newline which is causing your error. Try adding \r to the [ \t] pattern to ignore it.
#Cyclone wrote:
Change your fprintf() statement to fprintf(stderr, "At line %d %s", yylineno, s); not that it will solve your problem.
The OP wrote:
You mean I should add \r into \t so the new regex for it will be [\r\t] Am I right ?
#rici wrote:
#chris suggests [ \r\t]. If you have Windows somewhere in the loop, I agree.
I am writing a front end for my C compiler, where in I am adding Type system currently. Previously I assumed everything was an int and hence the following rule worked fine.
declaration: datatype varList ';' { gTrace<<"declaration ";}
varList: IDENTIFIER { builder.addSymbol($1); }
| varList',' IDENTIFIER { builder.addSymbol($3); }
;
But now I also add type to the symbol, and hence modified my rule like below:
declaration: datatype { currentType = $1; } varList ';' { gTrace<<"declaration "; currentType = -1; }
varList: IDENTIFIER { builder.addSymbol($1, getType(currentType)); }
| varList',' IDENTIFIER { builder.addSymbol($3, getType(currentType)); }
;
I get a shift/reduce error when I do that, since the { currentType = $1; } is being considered as an empty rule. How do I go about this error? Is there a way to specify that it is just an action?
Attached below is a snippet from my y.output
32 $#6: /* empty */
33 declaration: datatype $#6 varList ';'
34 varList: IDENTIFIER
35 | varList ',' IDENTIFIER
I don't get any error or warnings:
%token INT
%token FLOAT
%token CHAR
%token IDENTIFIER
%%
declaration: datatype { currentType = $1; } varList ';' { gTrace<<"declaration "; currentType = -1; }
varList : IDENTIFIER { builder.addSymbol($1, getType(currentType)); }
| varList ',' IDENTIFIER { builder.addSymbol($3, getType(currentType)); }
;
datatype: INT
| FLOAT
| CHAR
;
%%
Command
% bison p.yacc
%
I think you will need to provide more information.
The full yacc file and the parameters you are passing to yacc/bison
Edit
I tried your file (as per the comment) I still get no errors or warnings:
> yacc --version
bison (GNU Bison) 2.3
Written by Robert Corbett and Richard Stallman.
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
I fixed the problem as below:
declaration: datatype varList ';' { gTrace<<"declaration "; currentType = -1; }
varList: IDENTIFIER { builder.addSymbol($1, getType(currentType)); }
| varList',' IDENTIFIER { builder.addSymbol($3, getType(currentType)); }
;
datatype: INTEGER { gTrace<<"int "; $$ = currentType = Type::IntegerTy; }
| FLOAT { gTrace<<"float "; $$ = currentType = Type::FloatTy; }
| VOID { gTrace<<"void "; $$ = currentType = Type::VoidTy; }
;
#sarnold, hope this helps!
I thing you can only define an actions block for each rule, so
declaration: datatype { currentType = $1; } varList ';' { gTrace<<"declaration "; currentType = -1; }
should be done as
declaration: datatype varList ';' { currentType = $1; gTrace<<"declaration "; currentType = -1; }
Anyway, you are setting currentType to the lexical value of datatype and to -1 right after