%{ #include #include #include #include #include #include #include #include extern struct TMValueType Integer; extern struct TMValueType Text; extern struct TMValueType TextSet; TMValueType vt; TMTopicMap q_topicmap; TM tm; TMPool parse_pool; TMStack pypair_pstack; TMStack pypair_vstack; TMQLNode parse_tree; static TMQLNode make_node(TMQLNodeType type, int nargs, ...); %} %union { int intval; double floatval; char *strval; void *voidval; TMQLNode nodeval; } %token URI %token NAME %token INTEGER %token TEXT %token TEXTSET %left OR %left AND %left NOT %token SELECT WHERE SUBJECT INSERT null ASTERISK DARROW %type operator %type value %type predicate %type where_clause %type property_condition %type select_statement %type prop_commalist %type pvpair_commalist %type subject %type pvpair %% tmql: select_statement { parse_tree = $1; } ; select_statement: SELECT where_clause { $$ = make_node(TM_QLNODE_SELECT,2,NULL,$2); } | SELECT prop_commalist where_clause { $$ = make_node(TM_QLNODE_SELECT,2,$2,$3); } ; prop_commalist: prop_commalist ',' URI { $$ = make_node(TM_QLNODE_PROPLIST,2,$3,$1); } | URI { $$ = make_node(TM_QLNODE_PROPLIST,2,$1,NULL); } | ASTERISK { $$ = make_node(TM_QLNODE_PROPLIST,2,NULL,NULL); } ; where_clause: WHERE property_condition { $$ = $2; } ; property_condition: property_condition OR property_condition { $$ = make_node(TM_QLNODE_OR,2, $1,$3); } | property_condition AND property_condition { $$ = make_node(TM_QLNODE_AND,2, $1,$3); } | NOT property_condition { $$ = $2; } | '(' property_condition ')' { $$ = $2; } | predicate ; predicate: URI operator value { $$ = make_node(TM_QLNODE_PREDICATE,3, $1,$2,$3); } | URI operator subject { $$ = make_node(TM_QLNODE_PREDICATE,3, $1,$2,$3); } ; value: INTEGER { $$ = make_node(TM_QLNODE_VALUE,2,&Integer,$1); } | TEXT { $$ = make_node(TM_QLNODE_VALUE,2,&Text,$1); } | TEXTSET { $$ = make_node(TM_QLNODE_VALUE,2,&TextSet,$1); } | null { $$ = make_node(TM_QLNODE_VALUE,2,NULL,NULL); } ; operator: NAME { /*printf(" -- operator '%s'--\n", $1);*/ $$ = $1; } ; subject: '{' pvpair_commalist '}' { $$ = make_node(TM_QLNODE_SUBJECT,1,$2); } ; pvpair_commalist: pvpair { $$ = make_node(TM_QLNODE_PVPAIRLIST,2,$1,NULL);} | pvpair_commalist ',' pvpair { $$ = make_node(TM_QLNODE_PVPAIRLIST,2,$3,$1);} ; pvpair: URI DARROW value { $$ = make_node(TM_QLNODE_PVPAIR,2,$1,$3); } ; %% TMQLNode make_node(TMQLNodeType type, int nargs, ...) { TMQLNode self,*p; va_list ptr; int i; TMTRACE(TM_QUERY_TRACE,"enter for type %s, nargs=%d\n" _ tm_qlnode_type_string(type) _ nargs); self = TM_ALLOC(parse_pool,sizeof(struct TMQLNode) + ( (nargs-1) * sizeof(TMQLNode) ) ); self->pool = parse_pool; self->line = 0; self->pos = 0; self->tm = tm; self->type = type; self->nargs = nargs; for(i=0;iargs[i] = NULL; p = self->args; va_start(ptr, nargs); while (--nargs >= 0) { *p++ = va_arg (ptr, TMQLNode); } #if 0 #ifndef NDEBUG for(i=0;inargs;i++) if( self->args[i] == NULL) { TMTRACE(TM_QUERY_TRACE,"ARG %d is NULL\n" _ i); } #endif #endif TM_RETURN(self); } #if 0 tmql: select_statement { parse_tree = $1; } ; tmql: insert_statement { parse_tree = $1; } ; predicate: URI operator value { TMError e; printf("P:'%s' OP'%s' val'%s'\n", $1,$2,tm_value_as_string(vt,$3,NULL,0)); TM_NEW(current_cetree); current_cetree->tree_op = TM_CETREE_OP_SIMPLE_CONDITION; e = tm_topicmap_get_property_by_name(q_topicmap,$1, &(current_cetree->prop)); if(e != TM_OK) { yyerror(tm_get_error(tm_topicmap_get_tm(q_topicmap))); } current_cetree->op = tm_valuetype_parse_opstring(vt,$2); current_cetree->arg = $3; $$ = current_cetree; } ; operator: NAME { printf(" -- operator '%s'--\n", $1); $$ = $1; } ; /* -------------------- INSERT -------------------- */ insert_statement: INSERT subject { struct TMSubject sbj; TMError e; char *uri,*value,*p; sbj.N = 0; while( tm_stack_size(pypair_pstack) > 0 ) { char buf[100]; bzero(buf,100); uri = (const char*)tm_stack_pop(pypair_pstack); value = tm_stack_pop(pypair_vstack); p = strrchr(uri,'/'); p++; strncpy(buf,uri,p-uri); sbj.props[sbj.N].model = buf; sbj.props[sbj.N].name = p; sbj.props[sbj.N].value = value; sbj.N++; } tm_stack_delete(&pypair_pstack); tm_stack_delete(&pypair_vstack); e = tm_topicmap_add_subject(q_topicmap,&sbj,NULL); assert(e == TM_OK); } ; { assert(pypair_vstack == NULL); pypair_pstack = tm_stack_new(10); pypair_vstack = tm_stack_new(10); } tm_stack_push(pypair_pstack,$1); tm_stack_push(pypair_vstack,$3); } ; %% #endif #if 0 | TEXTSET { $$ = make_node(TM_QLNODE_VALUE,2,&TextSet,$1); } ; static DSQL_NOD make_node ( NOD_TYPE type, int count, ...) { /************************************** * * m a k e _ n o d e * ************************************** * * Functional description * Make a node of given type. * Any change should also be made to function below * **************************************/ DSQL_NOD node, *p; va_list ptr; TSQL tdsql; tdsql = GET_THREAD_DATA; node = FB_NEW_RPT(*tdsql->tsql_default, count) dsql_nod; node->nod_type = type; node->nod_line = (USHORT) lex.lines_bk; node->nod_column = (USHORT) (lex.last_token_bk - lex.line_start_bk + 1); node->nod_count = count; p = node->nod_arg; va_start(ptr, count); while (--count >= 0) *p++ = va_arg (ptr, DSQL_NOD); return node; #endif