I am writing a lexical analyzer here is the code:
%{
#include <stdio.h>
void showToken(char*);
%}
%%
int main(){
void showToken(char* name){
printf("<%s,%s>",name,yytext);
}
return 0;
}
%%
I am getting the following :
~/hedor1>cc -c -o lexical.o lexical.c
lexical.l:40: error: expected identifier or â(â before â%â token
I cant find where is the problem and moreover in the CODE SECTION must I write :
int main(){}
what happens if I don't write the main function above?
Primary problem
You can only have two %% lines in a Lex (Flex) analyzer.
...definitions...
%%
...lexical patterns...
%%
...everything else...
The programs Lex and Flex simply copy the content of the file after the second %% verbatim into the generated C code. And C doesn't like %% at any time.
Nitpick
You shouldn't nest functions inside each other like you're trying to with:
int main(){
void showToken(char* name){
printf("<%s,%s>",name,yytext);
}
return 0;
}
You need to separate main() from showToken(). (There is a GCC-specific extension that does allow nested functions. Don't use it.)
Also, when you have a line number in an error message, it is helpful to insert a comment to identify the line in the source. Or describe the line that is identified. But we shouldn't have to count the lines in your code, even if the error is in line 1...well, maybe lines 1-3 aren't too critical, but there is a fuzzy breakpoint after which identifying the line is important. By the time is has reached the teens, it is close to essential; the first 5 lines probably aren't crucial; in between (6-12) it's generally better to indicate the line number.
Related
I found it easy to learn about Lex/Flex however learning Yacc/Bison seemed a lot more confusing due to the lack of simple example programs. From my observations, the first example parser introduced to students tends to be a calculator, which is not too beginner-friendly. It was quite hard for me to comprehend how Yacc works simply by looking at complex source code, thus I decided to write my own very simple program which incorporates Lex and Yacc.
test.l:
%{
#include "y.tab.h"
%}
%%
"PRINT" { printf("Returning PRINT\n"); return PRINT; }
"EXIT" { printf("Returning EXIT\n"); return EXIT; }
. ;
[ \t\n] ;
%%
int yywrap(void) { return 1; }
test.y:
%{
int yylex();
#include <stdio.h>
#include <stdlib.h>
//#include "y.tab.h"
%}
%start line
%token PRINT
%token EXIT
%%
line: PRINT {printf("Caught PRINT\n");}
| EXIT {printf("Caught EXIT\n");}
| ;
%%
int main() { yyparse(); }
Compilation:
yacc -d test.y
lex test.l
gcc lex.yy.c y.tab.h -ll
I understand that this program is very simple and there are tons of examples for Yacc, I would like to sincerely assure you that I tried for a couple hours before asking out for some help.
Although I think I got the basics done, I'm unable to figure out why it won't work, please let me know how I could fix it. I suspect that I might be compiling incorrectly. I could also display y.tab.h if necessary. Thank you for your time.
Edit: The goal is simply for the lexer to return the appropriate return value to the yacc parser, and for the yacc parser to "catch" it and print "Caught PRINT" or "Caught EXIT".
Edit 2: My compilation process was indeed incorrect. I would like to thank the person who was helped me understand how to fix the issue.
You shouldn't compile *.h files.
Withgcc y.tab.c lex.yy.c and a provided yyerror definition inside test.y (the bison manual recommends void yyerror (char const *s) { fprintf (stderr, "%s\n", s); }), it should build.
I am trying to understand lex/yacc and currently I am failing at hello world. I probably messed something up, somewhere, but I can't seem to find it.
Also, I am not experienced with C language or with lex/flex/yacc/bison so this is all new to me.
test.l file;
%option noyywrap
%{
#include <stdio.h>
%}
%%
"hey" printf("hello!");
%%
int main()
{
return 0;
}
I compile this on windows, with the commands;
lex test.l
This returns lex.yy.c file without errors or warnings.
I then compile with;
cc lex.yy.c
Which without errors or warnings, creates the a.exe as supposed too.
When i then run the file with input from another file;
a.exe < input
It returns nothing.
Input file;
"hey"
Any information is welcome, since every single guide I found either creates errors (when literally copy pasted, even after clean install and guided-install) or is simply outdated or listed for "windows" while it uses commands that are non-windows >.<
It's the double quotes in the "hey" in your .l file they actually don't mean "hey" they mean hey so if you change your input file to just say hey rather than "hey" your code should work. If you want to parse " then your rule should be: "\"hey\""
Also lex should auto include stdio.h so you probably don't need it.
LOL you forgot to call yylex();
So:
%option noyywrap
%%
"hey" printf("hello!");
%%
int main()
{
yylex();
return 0;
}
Important subtlety
You will see this behaviour occur and you may not notice it right away but
Your original code will give you and output. The match will occur even with \"hey\" output and you will get:
"hello!"
Notice the "'s.
That's because lex injects a default rule for any character matching to just spit it back out, and because your "hey" rule matches hey and you have "'s around the input the quotes come out in the "hello!"
Your main does nothing - you need to call the lexer.
int main()
{
yylex();
return 0;
}
So we have a tutorial on flex,bison before we start our complation techniques course at university.
The following test should be split into lines and newlines
testtest test data
second line in the data
another line without a trailing newline
This is what my parser should output:
Line: testtest test data
NL
Line: second line in the data
NL
Line: another line without a trailing newline
When im running following
cat test.txt | ./parser
This returns:
LINE: testtest test data
It's a bad: syntax error
This is in my .y file:
%{
#include<stdio.h>
int yylex(); /* Supress C99 warning on OSX */
extern char *yytext; /* Correct for Flex */
unsigned int total;
%}
%token LINE
%token NL
%%
line : LINE {printf("LINE: %s\n", yytext);}
;
newline : NL {printf("NL\n");}
;
And this is in my binary.flex file:
%top{
#define YYSTYPE int
#include "binary.tab.h" /* Token values generated by bison */
}
%option noyywrap
%%
[^\n\r/]+ return LINE;
\n return NL;
%%
So, any ideas to solve this problem ?
PS: This is my .c file
#include<stdio.h>
#include "binary.tab.h"
extern unsigned int total;
int yyerror(char *c)
{
printf("It's a bad: %s\n", c);
return 0;
}
int main(int argc, char **argv)
{
if(!yyparse())
printf("It's a mario time: %d\n",total);
return 0;
}
Your bison grammar recognizes precisely one LINE (without a newline) because the bison grammar recognizes the first non-terminal. Just that, and no more.
If you want to recognize multiples lines, each consisting of a LINE and possibly a NL, you'll need to add a definition for an input consisting of multiple lines, each consisting of ... . I'm not sure why you would use bison for this, though, since the original problem seems easy to solve with just flex.
By the way, if your input file includes a \r character, none of your flex patterns will recognize it (the flex-generated default rule will catch it, but that is almost never what you want). Use %option nodefault so that you get a warning about this sort of error. And react when you see warnings: you will have seen several when you ran bison on your bison file, I'm sure.
I am following along a tutorial for C programming in 6502 Assembly and am having a great deal of difficulty on the 3rd step. When compiling my code in the command line, i get these errors:
test4.c(8): Error: '{' expected
test4.c(9): Warning: Function must be extern
test4.c(9): Error: ';' expected
test4.c(13): Error: '}' expected
I am using a program to compile .c files made in code::blocks to .nes files. The current tutorial is having me also make .s assembly file when compiling in the cl65 command line in Windows from the program that is compiling it. Here is the link to the tutorial page i am on:
https://helloacm.com/tutorial-3-c-programming-in-6502-using-assembly/
I have tried many different combinations of code that i can think of to try and get rid of a least some of the problems, but alas to no avail. I am an amateur in C, usually use C++ but i cannot and still trying to figure this out. I was not able to find the "Function must be extern" error anywhere with a quick google search either. Anyone have an idea what's going on?
Here is how i wrote the code in code::blocks:
void main()
{
asm("nop");
}
void testasm()
void main()
{
while(1) {
testasm(); // call the assembled function
}
}
Also, had a really difficult time following along on this particular tutorial part.
Thanks in advance, any help is appreciated on diagnosing the problem!
Perhaps this is what you're after?
void testasm()
{
asm("nop");
}
void main()
{
while(1) {
testasm(); // call the assembled function
}
}
Your code had two main() functions, and a prototype void testasm() with no terminating semicolon.
Alternatively, if testasm is written in assembly, your code should look like this (removing the extra main function):
extern void testasm(); // `extern` not specifically required, but may be for
// your particular compiler
void main()
{
while(1) {
testasm(); // call the assembled function
}
}
You need to be much more careful writing code.
I am new to C programming and I am currently learning loops. In the below program,
#include<stdio.h>
main()
{
int i;
for(i=1;i++<=5;printf("%d",i));
}
i tried to compile in dev c++ compiler but it is giving error "[Error] ld returned 1 exit status"
You need to include the <stdio.h> header, and also, main needs a return type (int) and a return value. Changing the program to this will make it compile (at least it did using GCC) and run:
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
for(i=1;i++<=5;printf("%d",i));
return 0;
}
The quotes you used in the “%d” are illegal too, use normal quotes: "%d".
Apart from that, doing the printf inside the loop head might be legal, but it's pretty bad style. Usually in a for-loop you would have have initialization;condition;increment(or decrement or w/e) in the head, and do side-effects in the body of the statement.
I would try writing the for loop as:
for(i=1;i < 6;i++) { printf(“%d”,i); }
I have run this program manually on my notebook and i got Output 23456
Then i run this on Dev c++ and it is giving the same output 23456 without any error and i have just copied and pasted from ur question dun know why its showing error on ur runtime may be u have not saved it as C file