extern char* g_str;
extern size_t g_str_size; /* taille de g_str */
extern int g_str_read; /* nombre de caractère déjà envoyés à lex, initializé au départ à 0 */
int my_yyinput(char* buf, int max_size)
{
/* on calcule le nombre de caractères à copier dans buf,
* soit on a assez de caractères pour remplir, buf, soit on prend le reste de la chaine
*/
int num = fmin(max_size, g_str_size-g_str_read);
/* on copie notre chaine dans buf */
if (num > 0)
{
memcpy(buf, g_str+g_str_read, num);
g_str_read += num;
}
return num;
}
{INTEGER} {yylval=atoi(yytext); return TOK_NUMBER;}
heat return TOK_HEAT;
on|off {yylval=!strcmp(yytext,"on"); return TOK_STATE;}
set return TOK_SET;
temperature return TOK_TEMPERATURE;
get return TOK_GET;
\n return TOK_EOL; /* end of line */;
[ \t]+ /* ignore whitespace */;
%%
main.y
%{
#include <stdio.h>
#include <string.h>
#define STR_SIZE 50
char g_str[STR_SIZE];
/*char* g_str;*/
size_t g_str_size; /* taille de g_str */
int g_str_read; /* nombre de caractère déjà envoyés à lex, initializé au départ à 0 */
/*
#define STR_SIZE 50
char str[STR_SIZE];
int myinput(char *buf, int max){
memcpy(buf, str, STR_SIZE);
}
*/
/*
int n = min(max, gStringLimit-gStringPtr);
if(n>0){
memcpy(buf, gStringPtr, n);
gStringPtr +=n;
}
return n;
}
*/
int value; /* temperature value */
enum _state {
off,
on
};
enum _state state;
void show_heat_state() {
if (state==off) {
printf("\tHeat is off\n");
} else {
printf("\tHeat is on\n");
}
}
[^] # Re: YY_INPUT
Posté par scls19fr (site web personnel) . En réponse au message Parser une chaine de caractère en C avec Flex/Bison. Évalué à 1.
main.l
%{
#include <string.h>
#include "main.tab.h"
#undef YY_INPUT
#define YY_INPUT(b,r,ms) (r = my_yyinput(b, ms))
extern char* g_str;
extern size_t g_str_size; /* taille de g_str */
extern int g_str_read; /* nombre de caractère déjà envoyés à lex, initializé au départ à 0 */
int my_yyinput(char* buf, int max_size)
{
/* on calcule le nombre de caractères à copier dans buf,
* soit on a assez de caractères pour remplir, buf, soit on prend le reste de la chaine
*/
int num = fmin(max_size, g_str_size-g_str_read);
/* on copie notre chaine dans buf */
if (num > 0)
{
memcpy(buf, g_str+g_str_read, num);
g_str_read += num;
}
return num;
}
%}
%option case-insensitive
INTEGER [0-9]+
FLOATING [-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?
%%
{INTEGER} {yylval=atoi(yytext); return TOK_NUMBER;}
heat return TOK_HEAT;
on|off {yylval=!strcmp(yytext,"on"); return TOK_STATE;}
set return TOK_SET;
temperature return TOK_TEMPERATURE;
get return TOK_GET;
\n return TOK_EOL; /* end of line */;
[ \t]+ /* ignore whitespace */;
%%
main.y
%{
#include <stdio.h>
#include <string.h>
#define STR_SIZE 50
char g_str[STR_SIZE];
/*char* g_str;*/
size_t g_str_size; /* taille de g_str */
int g_str_read; /* nombre de caractère déjà envoyés à lex, initializé au départ à 0 */
/*
#define STR_SIZE 50
char str[STR_SIZE];
int myinput(char *buf, int max){
memcpy(buf, str, STR_SIZE);
}
*/
/*
int n = min(max, gStringLimit-gStringPtr);
if(n>0){
memcpy(buf, gStringPtr, n);
gStringPtr +=n;
}
return n;
}
*/
int value; /* temperature value */
enum _state {
off,
on
};
enum _state state;
void show_heat_state() {
if (state==off) {
printf("\tHeat is off\n");
} else {
printf("\tHeat is on\n");
}
}
%}
%token TOK_NUMBER TOK_HEAT TOK_STATE TOK_SET TOK_TEMPERATURE TOK_GET TOK_EOL
%%
commands: /* empty */
| commands command TOK_EOL
;
command:
heat_switch
|
heat_get
|
target_set
|
target_get
;
heat_switch:
TOK_HEAT TOK_STATE
{
if (2ドル==0) {
state=off;
} else if (2ドル==1) {
state=on;
}
show_heat_state();
}
;
heat_get:
TOK_GET TOK_HEAT
{
show_heat_state();
}
;
target_set:
TOK_SET TOK_TEMPERATURE TOK_NUMBER
{
value=3ドル;
printf("\tTemperature set to %d\n",value);
}
;
target_get:
TOK_GET TOK_TEMPERATURE
{
printf("\tTemperature is %d\n",value);
}
;
%%
void yyerror(const char *str) {
fprintf(stderr,"yyerror: %s\n",str);
}
int yywrap() {
return 1;
}
int main(void) {
strcpy(g_str,"get temperature");
/* printf(g_str); */
value=0;
state=off;
yyparse();
return 0;
}
Makefile
all:
flex main.l
bison -d main.y
gcc lex.yy.c main.tab.c -lfl -o main
./main