Process a config file in FLEX (lexical generator) - flex-lexer

I'm trying to process in flex a config file, which looks like this
[Tooldir]
BcLib=C:\APPS\BC\LIB
BcInclude=C:\APPS\BC\INCLUDE
[IDE]
DefaultDesktopDir=C:\APPS\BC\BIN
HelpDir=C:\APPS\BC\BIN
[Startup]
State=0
Left=21
Right=21
Width=946
Height=663
[Project]
Lastproj=c:\apps\bc\bin\proj0002.ide
So it would look like this
[Tooldir]
[IDE]
[Startup]
[Project]
I'm currently trying with states, but I just don't seem to understand how they work.
%{
#include <stdio.h>
int yywrap(void);
int yylex(void);
%}
%s section
%%
/* == rules == */
<INITIAL>"[" BEGIN section;
<section>. printf("%s",yytext);
<section>"]\n" BEGIN INITIAL;
%%
int yywrap(void) { return 1; }
int main() { return yylex(); }
The code above is printing everything except the "[" and "]"... Some help, please?
EDIT:
Working code
%{
#include <stdio.h>
int yywrap(void);
int yylex(void);
%}
%s section
%%
/* == rules == */
<INITIAL>"[" BEGIN section; printf("[");
<section>. printf("%s",yytext);
<section>"]\n" BEGIN INITIAL; printf("]\n");
.|\n {;}
%%
int yywrap(void) { return 1; }
int main() { return yylex(); }

By default, anything that doesn't match any of the flex rules is printed. So your rules match the [whatever] lines and print whatever (removing the [ and ]), while the default rule matches everything else (printing it).
Add a rule like:
.|\n { /* ignoring all other unmatched text */ }
to the end of your rules if you want to ignore everything else, rather than printing it.

Related

print from user to screen with (enter)

i'am tray to print a strings from user to screen the problem i faced that i nedd when user insert (enter)key the program go to new line and user still have the ability to print on screen , but when i insert (enter)the program go to the first line and overwrite the old words here is my code
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main()
{
int len;
char searsh_word[10];
char ch;
printf("enter your strings\n");
while(ch!='EOF'){
ch=getch();
printf("%c",ch);
}
puts("\nEnter the word you need to search for : ");
scanf("%s",searsh_word);
len=strlen(searsh_word);
printf("your word length is : %d",len);
return 0;
}
the problem was by useing getch() you can use grtchar() for better result
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
FILE *file;
int main()
{
int len;
char searsh_word[10];
char ch;
file=fopen("test.txt","w");
if(!file){
printf("Error opening file\n");
exit(1);
}else{
printf("enter your strings\n");
}
do{
ch=getchar();
fprintf(file,"%c",ch);
}while(ch!='.');
fclose(file);
puts("\nEnter the word you need to search for : ");
scanf("%s",searsh_word);
len=strlen(searsh_word);
printf("your word length is : %d",len);
return 0;
}

Sorting char array in ascending order (with Link list)

I want to arrange my link list (which contains char arrays) in ascending order. This program should allow the user to input some names and then display them in ascending order. I have used the strncpy function. There are no compilation errors.But instead of names, the output gives some integers (perharps addresses). Please help me! I am new to C!
#include <stdio.h>
#include <malloc.h>
#include <string.h>
char name [10];
struct node
{
char nm [10];
struct node *next;
}*newnode, *prev, *temp, *display, *current, *list;
void createlist()
{
list=NULL;
};
void insert ()
{
newnode=(struct node*) malloc (sizeof (struct node));
printf("Enter the Name: ");
scanf("%s",&name);
strncpy(newnode->nm,name, 10);
newnode->next=NULL;
if (list==NULL)
{
list=newnode;
}
else if (name<list->nm)
{
newnode->next=list;
list=newnode;
}
else
{
temp=list;
int place;
place=0;
while (temp!=NULL && place ==0)
{
if (name>temp->nm)
{
prev=temp;
temp=temp->next;
}
else
{
place=1;
}
newnode->next=prev->next;
prev->next=newnode;
}
}
}
void displayname()
{
if (list==NULL)
printf("\n\nList is empty");
else
{
display=list;
while(display!=NULL)
{
printf("%d\n",display->nm);
display=display->next;
}
}
}
int main()
{
char choice;
choice=='y';
createlist();
do
{
insert ();
printf("Do you want to continue? ");
scanf("%s",&choice);
}while (choice='y'&& choice!='n');
displayname();
}
In the display function you have
printf("%d\n",display->nm);
The %d formatter outputs the argument as an integer. Use printf's %s formatter to get character arrays
printf("%s\n",display->nm);
You will still need to write the sorting code ... put the problem of outputtin numbers instead of text.

Who modify the type of $$ in a yacc grammar

I want to change the define $$ as a struct in the following grammar i have declared yylval as str, but i have errors when compile the .c file with gcc
gcc *.c -ly
tp.l: In function ‘yylex’:
tp.l:12: error: request for member ‘sum’ in something not a structure or union
y.tab.c:1035: error: conflicting types for ‘yylval’
tp.y:11: note: previous declaration of ‘yylval’ was here
the yacc file:
%{
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int val;
int cpt;
} str;
str yylval;
%}
%start start
%token number
%%
start : number'+'number'\n'
;
%%
int main(void)
{
yyparse();
return 0;
}
the lex file :
%option noyywrap
%{
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include"y.tab.h"
%}
%%
[0-9]+ {
yylval = atoi(yytext);
return number;
}
"+" return '+';
\n return '\n';
" " ;
%%
You cannot define your own yylval. The generated code already defines this. Use the %union directive to define the type indirectly. If that is not suitable, then what you can do is redefine the macro YYSTYPE which expands to arbitrary type specifiers. For instance:
struct my_semantic_attributes {
int foo;
/* ... */
};
#define YYSTYPE struct my_semantic_attributes

Values in $1, $2 .. variables always NULL

I am trying to create a parser with Bison (GNU bison 2.4.1) and flex (2.5.35) on my Ubuntu OS. I have something like this:
sql.h:
typedef struct word
{
char *val;
int length;
} WORD;
struct yword
{
struct word v;
int o;
...
};
sql1.y
%{
..
#include "sql.h"
..
%}
%union yystype
{
struct tree *t;
struct yword b;
...
}
%token <b> NAME
%%
...
table:
NAME { add_table(root, $1.v); }
;
...
Trouble is that whatever string I give to it, when it comes to resolve this, v always has values (NULL, 0) even if the input string should have some table name. (I chose to skip unnecessary other details/snippets, but can provide more if it helps resolve this.)
I wrote the grammar which is complete and correct, but I can't get it to build the parse tree due to this problem.
Any inputs would be quite appreciated.
Your trouble seems related to some missing or buggous code in the lexical analyzer.
Check your lexical analyzer first.
If it does not return the token proprely the parser part can not handle correctly the values.
Write a basic test that print the token value.
Do not mind the "c" style, above all is the principle :
main() {
int token;
while( token = yylex() ) {
switch( token) {
case NAME:
printf("name '%s'\n", yylval.b.v.val );
break;
...
}
}
}
If you run some input and that does not work.
if the lexical analyzer does not set yylval when it returns NAME, it is normal that val is empty.
If in your flex you have a pattern such as :
[a-z]+ { return NAME; }
It is incorrect you have to set the value like this
[a-z]+ {
yylval.val = strdup(yytext);
yylval.length = yylen;
return NAME; }

Pushing an executable function pointer?

Usually one would only push 'userdata' when the data isn't any of Lua's standard types (number, string, bool, etc).
But how would you push an actually Function pointer to Lua (not as userdata; since userdata is not executable as function in Lua), assuming the function looks like so:
void nothing(const char* stuff)
{
do_magic_things_with(stuff);
}
The returned value should behave like the returned value from this native Lua function:
function things()
return function(stuff)
do_magic_things_with(stuff)
end
end
Is this possible to do with the C API? If yes, how (Examples would be appreciated)?
EDIT: To add some clarity, The value is supposed to be returned by a function exposed to Lua through the C API.
Use lua_pushcfunction
Examples are included in PiL
Here is an example that follows the form of the currently accepted answer.
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include <stdio.h>
/* this is the C function you want to return */
static void
cfunction(const char *s)
{
puts(s);
}
/* this is the proxy function that acts like cfunction */
static int
proxy(lua_State *L)
{
cfunction(luaL_checkstring(L, 1));
return 0;
}
/* this global function returns "cfunction" to Lua. */
static int
getproxy(lua_State *L)
{
lua_pushcfunction(L, &proxy);
return 1;
}
int
main(int argc, char **argv)
{
lua_State *L;
L = luaL_newstate();
/* set the global function that returns the proxy */
lua_pushcfunction(L, getproxy);
lua_setglobal(L, "getproxy");
/* see if it works */
luaL_dostring(L, "p = getproxy() p('Hello, world!')");
lua_close(L);
return 0;
}
You could return a userdata with a metatable that proxies your C function through the __call metamethod. That way the userdata could be called like a function. Below is a full program example.
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include <stdio.h>
/* this is the C function you want to return */
static void
cfunction(const char *s)
{
puts(s);
}
/* this is the proxy function that will be used as the __call metamethod */
static int
proxy(lua_State *L)
{
luaL_checkudata(L, 1, "proxy");
cfunction(luaL_checkstring(L, 2));
return 0;
}
/* this global function returns the C function with a userdata proxy */
static int
getproxy(lua_State *L)
{
lua_newuserdata(L, sizeof (int));
luaL_getmetatable(L, "proxy");
lua_setmetatable(L, -2);
return 1;
}
int
main(int argc, char **argv)
{
lua_State *L;
L = luaL_newstate();
/* create the proxy metatable */
luaL_newmetatable(L, "proxy");
lua_pushcfunction(L, proxy);
lua_setfield(L, -2, "__call");
/* set the global function that returns the proxy */
lua_pushcfunction(L, getproxy);
lua_setglobal(L, "getproxy");
/* see if it works */
luaL_dostring(L, "p = getproxy() p('Hello, world!')");
lua_close(L);
return 0;
}
In retrospect, I completely over-thought what you are asking. All you really need to do is to create a function of type lua_CFunction that pulls the parameters from the Lua stack and passes them on to the target C function. The code above answers your question literally, but it is probably overkill for what you really need to accomplish.

Resources