我正在使用flex和bison做一个简单的计算器,但它只读取输入文件的第一行。 这是我的野牛代码:
// If you have 1 or more bluetooth dongles attached to the system.
// this will select the first one, then it will perform a scan for
// all devices within range of that dongle and print out all the
// information available about each device. then move on to the next
// dongle and repeat the process, etc. doesn't actually DO much apart
// from find devices and display their information.
#include <stdlib.h>
#include <stdio.h>
// Link to ws2_32.lib
#include <Winsock2.h>
#include <Ws2bth.h>
// Link to Bthprops.lib
#include <BluetoothAPIs.h>
BLUETOOTH_FIND_RADIO_PARAMS m_bt_find_radio = { sizeof(BLUETOOTH_FIND_RADIO_PARAMS) };
BLUETOOTH_RADIO_INFO m_bt_info = { sizeof(BLUETOOTH_RADIO_INFO), 0, };
BLUETOOTH_DEVICE_SEARCH_PARAMS m_search_params = {
sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS),
1,
0,
1,
1,
1,
15,
NULL
};
BLUETOOTH_DEVICE_INFO m_device_info = { sizeof(BLUETOOTH_DEVICE_INFO), 0, };
// Note:
// Radio - is the thing plugged in/attached to the local machine.
// Device - is the thing that is connected to via the Bluetooth connection.
int main(int argc, char **args)
{
HANDLE m_radio = NULL;
HBLUETOOTH_RADIO_FIND m_bt = NULL;
HBLUETOOTH_DEVICE_FIND m_bt_dev = NULL;
int m_radio_id;
int m_device_id;
DWORD mbtinfo_ret;
// Iterate for available bluetooth radio devices in range
// Starting from the local
while (TRUE)
{
m_bt = BluetoothFindFirstRadio(&m_bt_find_radio, &m_radio);
if (m_bt != NULL)
printf("BluetoothFindFirstRadio() is OK!\n");
else
printf("BluetoothFindFirstRadio() failed with error code %d\n", GetLastError());
m_radio_id = 0;
do {
// Then get the radio device info....
mbtinfo_ret = BluetoothGetRadioInfo(m_radio, &m_bt_info);
if (mbtinfo_ret == ERROR_SUCCESS)
printf("BluetoothGetRadioInfo() looks fine!\n");
else
printf("BluetoothGetRadioInfo() failed wit herror code %d\n", mbtinfo_ret);
wprintf(L"Radio %d:\r\n", m_radio_id);
wprintf(L"\tInstance Name: %s\r\n", m_bt_info.szName);
wprintf(L"\tAddress: %02X:%02X:%02X:%02X:%02X:%02X\r\n", m_bt_info.address.rgBytes[5],
m_bt_info.address.rgBytes[4], m_bt_info.address.rgBytes[3], m_bt_info.address.rgBytes[2],
m_bt_info.address.rgBytes[1], m_bt_info.address.rgBytes[0]);
wprintf(L"\tClass: 0x%08x\r\n", m_bt_info.ulClassofDevice);
wprintf(L"\tManufacturer: 0x%04x\r\n", m_bt_info.manufacturer);
m_search_params.hRadio = m_radio;
ZeroMemory(&m_device_info, sizeof(BLUETOOTH_DEVICE_INFO));
m_device_info.dwSize = sizeof(BLUETOOTH_DEVICE_INFO);
// Next for every radio, get the device
m_bt_dev = BluetoothFindFirstDevice(&m_search_params, &m_device_info);
if (m_bt_dev != NULL)
printf("\nBluetoothFindFirstDevice() is working!\n");
else
printf("\nBluetoothFindFirstDevice() failed with error code %d\n", GetLastError());
m_radio_id++;
m_device_id = 0;
// Get the device info
do
{
wprintf(L"\n\tDevice %d:\r\n", m_device_id);
wprintf(L" \tInstance Name: %s\r\n", m_device_info.szName);
wprintf(L" \tAddress: %02X:%02X:%02X:%02X:%02X:%02X\r\n", m_device_info.Address.rgBytes[5],
m_device_info.Address.rgBytes[4], m_device_info.Address.rgBytes[3], m_device_info.Address.rgBytes[2],
m_device_info.Address.rgBytes[1], m_device_info.Address.rgBytes[0]);
wprintf(L" \tClass: 0x%08x\r\n", m_device_info.ulClassofDevice);
wprintf(L" \tConnected: %s\r\n", m_device_info.fConnected ? L"true" : L"false");
wprintf(L" \tAuthenticated: %s\r\n", m_device_info.fAuthenticated ? L"true" : L"false");
wprintf(L" \tRemembered: %s\r\n", m_device_info.fRemembered ? L"true" : L"false");
m_device_id++;
// Well, the found device information can be used for further socket
// operation such as creating a socket, bind, listen, connect, send, receive etc..
// If no more device, exit the loop
if (!BluetoothFindNextDevice(m_bt_dev, &m_device_info))
break;
} while (BluetoothFindNextDevice(m_bt_dev, &m_device_info));
// NO more device, close the device handle
if (BluetoothFindDeviceClose(m_bt_dev) == TRUE)
printf("\nBluetoothFindDeviceClose(m_bt_dev) is OK!\n");
else
printf("\nBluetoothFindDeviceClose(m_bt_dev) failed with error code %d\n", GetLastError());
} while (BluetoothFindNextRadio(&m_bt_find_radio, &m_radio));
// No more radio, close the radio handle
if (BluetoothFindRadioClose(m_bt) == TRUE)
printf("BluetoothFindRadioClose(m_bt) is OK!\n");
else
printf("BluetoothFindRadioClose(m_bt) failed with error code %d\n", GetLastError());
// Exit the outermost WHILE and BluetoothFindXXXXRadio loops if there is no more radio
if (!BluetoothFindNextRadio(&m_bt_find_radio, &m_radio))
break;
// Give some time for the 'signal' which is a typical for crap wireless devices
Sleep(1000);
}
return 0;
}
这是我的灵活代码:
%{
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "symtab.h"
extern int yylex(void);
extern char *yytext;
extern int num_linea;
extern FILE *yyin;
void yyerror(char *s);
%}
%union{
struct{
char *lexema;
int lenght;
int line;
}ident;
}
%union{
struct{
int integer;
float real;
char *string;
int type;
}num;
}
%union{
int num_int;
}
%union{
float num_float;
}
%token <ident> IDENT
%token <num> LIT_INT
%token <num> LIT_FLOAT
%token <num> CADENA
%token PARENTESIS1
%token PARENTESIS2
%token OP_SUM
%token OP_REST
%token OP_MULT
%token OP_DIV
%token OP_MOD
%token OP_POW
%token ASSIGN
%token NX_LINE
%token INVALID_TOKEN
%type <num> expr
%type <num> term
%type <num> factor
%type <num> primary
%type <num> linea
%%
linea : IDENT ASSIGN expr NX_LINE {/*sym_enter($1.lexema,(void *)&$3)*/;}
| OP_SUM expr NX_LINE {if($2.type==0) {
printf("El valor es %d. \n", $2.integer);
} else if($2.type==1) {
printf("El valor es %f. \n", $2.real);
}}
| OP_REST expr NX_LINE {if($2.type==0) {
printf("El valor es %d. \n", -$2.integer);
} else if($2.type==1) {
printf("El valor es %f. \n", -$2.real);
}}
| expr NX_LINE {if($1.type==0) {
printf("El valor es entero y es %d. \n", $1.integer);
} else if($1.type==1) {
printf("El valor es un float y es %f. \n", $1.real);
} else if($1.type==2) {
printf("El valor es un string y es %s. \n", $1.string);
}}
;
expr : expr OP_SUM term {if($1.type==0 && $3.type==0) {
$$.type=0;
$$.integer=$1.integer+$3.integer;
} else if($1.type==1 && $3.type==1) {
$$.type=1;
$$.real=$1.real+$3.real;
} else if($1.type==0 && $3.type==1) {
$$.type=1;
$$.real=$1.integer+$3.real;
} else if($1.type==1 && $3.type==0) {
$$.type=1;
$$.real=$1.real+$3.integer;
}else if($1.type==0 && $3.type==2) {
$$.type=2;
$$.string=malloc(sizeof($3.string)+sizeof($1.integer));
sprintf($$.string,"%d%s",$1.integer,$3.string);
} else if($1.type==1 && $3.type==2) {
$$.type=2;
$$.string=malloc(sizeof($3.string)+sizeof($1.real));
sprintf($$.string,"%f%s",$1.real,$3.string);
}else if($3.type==0 && $1.type==2) {
$$.type=2;
$$.string=malloc(sizeof($1.string)+sizeof($3.integer));
sprintf($$.string,"%s%d",$1.string,$3.integer);
} else if($3.type==1 && $1.type==2) {
$$.type=2;
$$.string=malloc(sizeof($3.real)+sizeof($1.string));
sprintf($$.string,"%s%f",$1.string,$3.real);
}}
| expr OP_REST term {if($1.type==0 && $3.type==0) {
$$.type=0;
$$.integer=$1.integer-$3.integer;
} else if($1.type==1 && $3.type==1) {
$$.type=1;
$$.real=$1.real-$3.real;
} else if($1.type==0 && $3.type==1) {
$$.type=1;
$$.real=$1.integer-$3.real;
} else if($1.type==1 && $3.type==0) {
$$.type=0;
$$.real=$1.real-$3.integer;
}}
| term {$$=$1;}
;
term : term OP_MULT factor {if($1.type==0 && $3.type==0) {
$$.type=0;
$$.integer=$1.integer*$3.integer;
} else if($1.type==1 && $3.type==1) {
$$.type=1;
$$.real=$1.real*$3.real;
} else if($1.type==0 && $3.type==1) {
$$.type=1;
$$.real=$1.integer*$3.real;
} else if($1.type==1 && $3.type==0) {
$$.type=0;
$$.real=$1.real*$3.integer;
}}
| term OP_DIV factor {if($1.type==0 && $3.type==0) {
$$.type=0;
$$.integer=$1.integer/$3.integer;
} else if($1.type==1 && $3.type==1) {
$$.type=1;
$$.real=$1.real/$3.real;
} else if($1.type==0 && $3.type==1) {
$$.type=1;
$$.real=$1.integer/$3.real;
} else if($1.type==1 && $3.type==0) {
$$.type=0;
$$.real=$1.real/$3.integer;
}}
| term OP_MOD factor {if($1.type==0 && $3.type==0) {
$$.type=0;
$$.integer=$1.integer%$3.integer;
} else if($1.type==1 && $3.type==1) {
$$.type=1;
$$.real=fmod($1.real,$3.real);
}}
| factor {$$=$1;}
;
factor : primary {$$=$1;}
| primary OP_POW factor {if($1.type==0 && $3.type==0) {
$$.type=0;
$$.integer=pow($1.integer,$3.integer);
} else if($1.type==1 && $3.type==1) {
$$.type=1;
$$.real=pow($1.real,$3.real);
}}
;
primary : PARENTESIS1 expr PARENTESIS2 {$$=$2;}
| PARENTESIS1 OP_REST expr PARENTESIS2 {if($3.type==0) {
$$.type=0;
$$.integer=-$3.integer;
} else if($3.type==1) {
$$.type=1;
$$.real=$3.real;
}}
| PARENTESIS1 OP_SUM expr PARENTESIS2 {$$=$3;}
| LIT_INT {$$=$1;}
| LIT_FLOAT {$$=$1;}
| CADENA {$$=$1;}
| IDENT {/*sym_lookup($1,$$)*/;}
;
%%
void yyerror(char *s)
{
printf("Error %s",s);
}
int main(int argc,char **argv)
{
if (argc>1)
yyin=fopen(argv[1],"rt");
else
yyin=stdin;
yyparse();
printf("FIN del Analisis. Entrada CORRECTA\n");
printf("Numero lineas analizadas: %d\n", num_linea);
return 0;
}
有了这个输入:
%{
#include "compilador1.tab.h"
#include <string.h>
#include <stdio.h>
#include <math.h>
int num_linea;
extern FILE *yyin;
%}
%option yylineno
%x comentario
%x comentario2
%x str
DIGIT [0-9]
ID [a-z][a-z0-9]*
%%
num_linea=1;
char string_buf[1000];
char *string_buf_ptr;
int string_cnt;
"\n" {printf("\n");num_linea++;return NX_LINE;}
"\t" {;}
" " {;}
"mod" {return OP_MOD;}
{DIGIT}+ {yylval.num.integer=atoi(yytext);yylval.num.type=0;printf("entero "); return LIT_INT;}
{DIGIT}+"."{DIGIT}* {yylval.num.real=atof(yytext);yylval.num.type=1;printf("real "); return LIT_FLOAT;}
{ID} {yylval.ident.lexema = (char *)malloc(sizeof(char)*yyleng);
strncpy(yylval.ident.lexema,yytext,yyleng);
yylval.ident.lenght = yyleng;
yylval.ident.line = yylineno;
printf("id ");
return IDENT;}
"/" {printf("div ");return OP_DIV;}
"**" {printf("pow ");return OP_POW;}
"*" {printf("mult ");return OP_MULT;}
"+" {printf("sum ");return OP_SUM;}
"-" {printf("rest ");return OP_REST;}
"(" {printf("( ");return PARENTESIS1;}
")" {printf(") ");return PARENTESIS2;}
":=" {printf("assign ");return ASSIGN;}
"/*" {BEGIN(comentario);}
<comentario>[^*\n]* /*ignora lo que no sea * */
<comentario>"*"+[^*/\n]* /*ignora los * no seguidos de / */
<comentario>\n {++num_linea;}
<comentario>"*"+"/" {BEGIN(INITIAL);}
"//" {BEGIN(comentario2);}
<comentario2>[^\n]
<comentario2>\n {BEGIN(INITIAL);}
\" string_buf_ptr = string_buf;string_cnt=0; BEGIN(str);
<str>\" { /* saw closing quote - all done */
BEGIN(INITIAL);
*string_buf_ptr = '\0';
/* return string constant token type and
* value to parser
*/
yylval.num.type=2;
yylval.num.string=string_buf_ptr-string_cnt;
printf("string ");
return CADENA;
}
<str>\n {
/* error - unterminated string constant */
/* generate error message */
}
<str>\\n *string_buf_ptr++ = '\n';
<str>\\t *string_buf_ptr++ = '\t';
<str>\\r *string_buf_ptr++ = '\r';
<str>\\b *string_buf_ptr++ = '\b';
<str>\\f *string_buf_ptr++ = '\f';
<str>\\(.|\n) *string_buf_ptr++ = yytext[1];
<str>[^\\\n\"]+ {
char *yptr = yytext;
while ( *yptr ) {
string_cnt++;
*string_buf_ptr++ = *yptr++;
}
}
. {printf("INVALID: %s", yytext); return INVALID_TOKEN;}
%%
我获得了这个输出:
4+5*6.4+"hello"
4+8
我的错误是什么?
答案 0 :(得分:1)
你的语法的开始非终端被称为“linea”,并且有充分的理由:它只定义了一行(unalínea)。 Bison解析器精确识别起始非终端,后跟文件结束,因此如果您的输入包含多行,则解析器在第一行之后遇到EOF以外的其他内容时将报告语法错误。 p>
如果你想识别多行,你需要编写一个匹配多行的语法:
programa : linea
| programa linea