- 论坛徽章:
- 0
|
我用flex和bison写一个很简单的程序,可是用gcc编译的时候怎么都不对,请大虾帮我看看。我已经快不行了,感觉这些编译的错误简直是莫名其妙
compile_6_30.l
- %{
- #include <stdio.h>;
- #include "common.h"
- #include "compile_6_30.tab.h"
- void yyerror(char *str);
- %}
- %%
- "int" return INT;
- "bool" return BOOL;
- "array" return ARRAY;
- "of" return OF;
- "or" return OR;
- "true" return TRUE;
- "false" return FALSE;
- "if" return IF;
- "then" return THEN;
- [a-zA-Z]* {
- /*int len=;*/
- yylval.id=(char *)malloc(strlen(yytext)+1);
- strncpy(yylval.id , yytext , strlen(yytext)+1);
- printf("id:%s\n" , yylval.id);
- return ID;
- }
复制代码
compile_6_30.y
- %{
- #include <stdio.h>;
- #include <stdlib.h>;
- #include "common.h"
- void yyerror(char *s);
- /*the function will try to search whether the id has been inserted
- if id has been inserted, the program exit with an error
- */
- void insert(char *id , nodetype *type);
- nodetype*new_type(nodetype *);
- void type_error(const char *);
- /*the nodetype is just a type expression
- so return nodetype pointer here
- */
- nodetype *lookup(const char *);
- /*
- if the length of one of arrays is zero, just compare their type
- */
- int type_equal(nodetype * , nodetype *);
- nodetype node1,node2,node3;
- #define INTEGER (&node1)
- #define BOOLEAN (&node2)
- #define ARRAYTYPE (&node3)
- table global_table;
- %}
- %union{
- char *id;
- int num;
- nodetype *ptr;
- }
- %token<id>; ID
- %token<num>; NUM
- %token INT BOOL IF THEN ASSIGN OF ARRAY OR TRUE FALSE
- %type <ptr>; program var_decls stmts var_decl type_exp stmt exp
- %%
- program:
- var_decls ';' stmts {}
- ;
- var_decls:
- var_decls ';' var_decl{}
- |var_decl {}
- var_decl:
- ID ':' type_exp {
- insert($1 , $3);
- free($3);
- }
- type_exp:
- INT {$$=new_type(INTEGER);}
- |BOOL {$$=new_type(BOOLEAN);}
- |ARRAY '[' NUM ']' OF type_exp {
- ARRAYTYPE->;len=$3;
- ARRAYTYPE->;child_type=$6;
- $$=new_type(ARRAYTYPE);
- free($6);
- }
- ;
- stmts:
- stmts ';' stmt {}
- |stmt {}
- ;
- stmt:
- IF exp THEN stmt {
- if(!type_equal($2 , BOOLEAN))
- type_error("exp in if-statement is not boolean");
- free($2);
- }
- |ID ASSIGN exp{
- if(!type_equal(lookup($1) , $3))
- type_error("the type is not coincident in the assign-statement");
- free($3);
- }
- ;
- exp:
- exp '+' exp {
- if(!type_equal($1 , INTEGER) || !type_equal($3 , INTEGER))
- type_error("the two exp are not coincident in add-statement");
- else
- $$=new_type(INTEGER);
- free($1);
- free($3);
- }
- |exp OR exp {
- if(!type_equal($1 , BOOLEAN) || !type_equal($3 , BOOLEAN))
- type_error("the two exp are not coincident in or-statement");
- else
- $$=new_type(BOOLEAN);
- free($1);
- free($3);
- }
- |exp '[' exp ']' {
- if(!type_equal($1 , ARRAYTYPE) || !type_equal($3 , INTEGER))
- type_error("the two exp are not coincident in array-statement");
- else
- $$=new_type($1->;child_type);
- free($1);
- free($3);
- }
- |NUM {
- $$=new_type(INTEGER);
- }
- |TRUE {
- $$=new_type(BOOLEAN);
- }
- |FALSE {
- $$=new_type(BOOLEAN);
- }
- |ID {
- $$=new_type(lookup($1));
- }
- ;
- %%
- void yyerror(char *s)
- {
- printf("%s\n" , s);
- exit(1);
- }
- /*the function will try to search whether the id has been inserted
- if id has been inserted, the program exit with an error
- and type will be free after the function,
- so here we must allocate a new space for it
- */
- void insert(char *id , nodetype *type)
- {
- int i;
- //check the parameter
- if(type == NULL)
- yyerror("the parameter of insert()--type is NULL");
- //check whether id is used
- for(i=0 ; i < global_table.size ; i++){
- if(strcmp(global_table.node[i].id , id) == 0){
- printf("id:%s has been used\n" , id);
- exit(1);
- }
- }
- //check whether there is enough space
- if(global_table.size == global_table.capacity){
- global_table.capacity<<=2;
- global_table.node=(tablenode *)realloc(global_table.node , global_table.capacity);
- if(global_table.node == NULL)
- yyerror("there is no enough space");
- }
- /*append the new node*/
- global_table.node[global_table.size].id=id;
- global_table.node[global_table.size].type=(nodetype *)malloc(sizeof(nodetype));
- memcpy(global_table.node[global_table.size].type , type , sizeof(nodetype));
- global_table.size++;
- }
- nodetype*new_type(nodetype *node)
- {
- if(node == NULL)
- yyerror("the parameter of new_type() -- node is NULL");
- nodetype *tmp=(nodetype *)malloc(sizeof(nodetype));
- memcpy(tmp , node , sizeof(nodetype));
- return tmp;
- }
- void type_error(const char *str)
- {
- yyerror(str);
- }
- /*the nodetype is just a type expression
- so return nodetype pointer here
- */
- nodetype *lookup(const char *id)
- {
- int i;
- if(id == NULL){
- printf("the parameter of lookup() -- id is NULL");
- return NULL;
- }
- for(i=0 ; i < global_table.size ; i++){
- if(strcmp(global_table.node[i].id , id))
- return (global_table.node+i)->;type;
- }
- return NULL;
- }
- /*
- if the length of one of arrays is zero, just compare their type
- */
- int type_equal(nodetype *node1 , nodetype *node2)
- {
- if(node1 == NULL){
- printf("the parameter of type_equal() -- node1 is NULL\n");
- return 0;
- }
- if(node2 == NULL){
- printf("the parameter of type_equal() -- node2 is NULL\n");
- return 0;
- }
- if(node1->;type != node2->;type)
- return 0;
- if(node1->;type == ARRAY){
- if(node1->;child_type->;type != node2->;child_type->;type)/*need modify*/
- return 0;
- return node1->;len == 0 || node2->;len == 0 || node1->;len == node2->;len;
- }
- return 1;
- }
- int main(int argc , char *argv[])
- {
- bzero(INTEGER , sizeof(nodetype));
- bzero(BOOLEAN , sizeof(nodetype));
- bzero(ARRAYTYPE , sizeof(nodetype));
- INTEGER->;type=INT;
- BOOLEAN->;type=BOOL;
- ARRAYTYPE->;type=ARRAY;
-
- global_table.capacity=ONE_BUF;
- global_table.size=0;
- global_table.node=(tablenode *)malloc(ONE_BUF);
- yyparse();
- exit(0);
- }
复制代码
common.h
- typedef struct nodeType
- {
- int type;
- char *id;
- struct
- {
- int len;
- struct nodeType *child;
- }u;
- #define len u.len
- #define child_type u.child
- }nodetype;
- typedef struct
- {
- char *id;
- nodetype *type;
- }tablenode;
- typedef struct
- {
- int capacity;
- int size;
- tablenode *node;
- }table;
- #define ONE_BUF 32
复制代码
我用下面的方式编译flex产生的.c文件:
bison -d compile_6_30.y
flex compile_6_30.l
gcc -c lex.yy.c
结果出来下面的错误
-*- mode: compilation; default-directory: "/windows/E/homework/project/" -*-
gcc -c lex.yy.c
compile_6_30.l: In function `yylex':
compile_6_30.l:33: warning: return makes integer from pointer without a cast
lex.yy.c: In function `yy_scan_string':
lex.yy.c:1394: error: syntax error before '.' token
lex.yy.c:1395: error: `u' undeclared (first use in this function)
lex.yy.c:1395: error: (Each undeclared identifier is reported only once
lex.yy.c:1395: error: for each function it appears in.)
lex.yy.c:1398: warning: passing arg 1 of `yy_scan_bytes' discards qualifiers from pointer target type
lex.yy.c: At top level:
lex.yy.c:1412: error: parse error before '.' token
lex.yy.c: In function `yy_scan_bytes':
lex.yy.c:1413: error: number of arguments doesn't match prototype
lex.yy.c:241: error: prototype declaration
lex.yy.c:1420: error: `u' undeclared (first use in this function)
lex.yy.c:1426: error: `bytes' undeclared (first use in this function)
Compilation exited abnormally with code 1 at Fri Jun 10 00:29:30
编译结果怎么会说有些变量找不到呢?
请大家帮帮忙
谢谢 |
|