野牛只读一行

时间:2015-10-11 18:00:51

标签: bison flex-lexer

我正在使用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

我的错误是什么?

1 个答案:

答案 0 :(得分:1)

你的语法的开始非终端被称为“linea”,并且有充分的理由:它只定义了一行(unalínea)。 Bison解析器精确识别起始非终端,后跟文件结束,因此如果您的输入包含多行,则解析器在第一行之后遇到EOF以外的其他内容时将报告语法错误。 p>

如果你想识别多行,你需要编写一个匹配多行的语法:

programa : linea
         | programa linea
相关问题