1 /*************************************************************************/
2 /*                                                                       */
3 /*                  Language Technologies Institute                      */
4 /*                     Carnegie Mellon University                        */
5 /*                       Copyright (c) 1999-2007                         */
6 /*                        All Rights Reserved.                           */
7 /*                                                                       */
8 /*  Permission is hereby granted, free of charge, to use and distribute  */
9 /*  this software and its documentation without restriction, including   */
10 /*  without limitation the rights to use, copy, modify, merge, publish,  */
11 /*  distribute, sublicense, and/or sell copies of this work, and to      */
12 /*  permit persons to whom this work is furnished to do so, subject to   */
13 /*  the following conditions:                                            */
14 /*   1. The code must retain the above copyright notice, this list of    */
15 /*      conditions and the following disclaimer.                         */
16 /*   2. Any modifications must be clearly marked as such.                */
17 /*   3. Original authors' names are not deleted.                         */
18 /*   4. The authors' names are not used to endorse or promote products   */
19 /*      derived from this software without specific prior written        */
20 /*      permission.                                                      */
21 /*                                                                       */
22 /*  CARNEGIE MELLON UNIVERSITY AND THE CONTRIBUTORS TO THIS WORK         */
23 /*  DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING      */
24 /*  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT   */
25 /*  SHALL CARNEGIE MELLON UNIVERSITY NOR THE CONTRIBUTORS BE LIABLE      */
26 /*  FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES    */
27 /*  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN   */
28 /*  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,          */
29 /*  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF       */
30 /*  THIS SOFTWARE.                                                       */
31 /*                                                                       */
32 /*************************************************************************/
33 /*             Author:  Alan W Black (awb@cs.cmu.edu)                    */
34 /*               Date:  April 2000                                       */
35 /*************************************************************************/
36 /*                                                                       */
37 /*  Item features and paths                                              */
38 /*                                                                       */
39 /*************************************************************************/
40 #include "cst_alloc.h"
41 #include "cst_item.h"
42 #include "cst_relation.h"
43 #include "cst_utterance.h"
44 #include "cst_tokenstream.h"
45 
46 CST_VAL_REGISTER_FUNCPTR(ffunc,cst_ffunction)
47 
48 DEF_STATIC_CONST_VAL_STRING(ffeature_default_val,"0");
49 
50 static const void *internal_ff(const cst_item *item,
51 			       const char *featpath,int type);
52 
ffeature_string(const cst_item * item,const char * featpath)53 const char *ffeature_string(const cst_item *item,const char *featpath)
54 {
55     return val_string(ffeature(item,featpath));
56 }
ffeature_int(const cst_item * item,const char * featpath)57 int ffeature_int(const cst_item *item,const char *featpath)
58 {
59     return val_int(ffeature(item,featpath));
60 }
ffeature_float(const cst_item * item,const char * featpath)61 float ffeature_float(const cst_item *item,const char *featpath)
62 {
63     return val_float(ffeature(item,featpath));
64 }
65 
path_to_item(const cst_item * item,const char * featpath)66 cst_item* path_to_item(const cst_item *item,const char *featpath)
67 {
68     return (cst_item *)internal_ff(item,featpath,1);
69 }
70 
ffeature(const cst_item * item,const char * featpath)71 const cst_val *ffeature(const cst_item *item,const char *featpath)
72 {
73     return (cst_val *)internal_ff(item,featpath,0);
74 }
75 
internal_ff(const cst_item * item,const char * featpath,int type)76 static const void *internal_ff(const cst_item *item,
77 			       const char *featpath,int type)
78 {
79     const char *tk, *relation;
80     cst_utterance *utt;
81     const cst_item *pitem;
82     void *void_v;
83     const cst_val *ff;
84     cst_ffunction ffunc;
85     char tokenstring[200]; /* we don't seem to have featpaths longer than 72 */
86     char *tokens[100];
87     int i,j;
88 
89     /* This used to use cst_tokenstream but that was too slow */
90     for (i=0; i<199 && featpath[i]; i++)
91         tokenstring[i] = featpath[i];
92     tokenstring[i]='\0';
93     tokens[0] = tokenstring;
94     for (i=0,j=1; tokenstring[i]; i++)
95     {
96         if (strchr(":.",tokenstring[i]))
97         {
98             tokenstring[i] = '\0';
99             tokens[j] = &tokenstring[i+1];
100             j++;
101         }
102     }
103     tokens[j] = NULL;
104     j=0;
105     for (tk = tokens[j], pitem=item;
106 	 pitem &&
107 	     (((type == 0) && tokens[j+1]) ||
108 	      ((type == 1) && tk));
109 	 j++, tk = tokens[j])
110     {
111 	if (cst_streq(tk,"n"))
112 	    pitem = item_next(pitem);
113 	else if (cst_streq(tk,"p"))
114 	    pitem = item_prev(pitem);
115 	else if (cst_streq(tk,"pp"))
116 	{
117 	    if (item_prev(pitem))
118 		pitem = item_prev(item_prev(pitem));
119 	    else
120 		pitem = NULL;
121 	}
122 	else if (cst_streq(tk,"nn"))
123 	{
124 	    if (item_next(pitem))
125 		pitem = item_next(item_next(pitem));
126 	    else
127 		pitem = NULL;
128 	}
129 	else if (cst_streq(tk,"parent"))
130 	    pitem = item_parent(pitem);
131 	else if ((cst_streq(tk,"daughter")) ||
132 		 (cst_streq(tk,"daughter1")))
133 	    pitem = item_daughter(pitem);
134 	else if (cst_streq(tk,"daughtern"))
135 	    pitem = item_last_daughter(pitem);
136 	else if (cst_streq(tk,"first"))
137 	    pitem = item_first(pitem);
138 	else if (cst_streq(tk,"last"))
139 	    pitem = item_last(pitem);
140 	else if (cst_streq(tk,"R"))
141 	{
142 	    /* A relation move */
143             j++;
144 	    relation = tokens[j];
145 	    pitem = item_as(pitem,relation);
146 	}
147 	else
148 	{
149 	    cst_errmsg("ffeature: unknown directive \"%s\" ignored\n",tk);
150 	    return NULL;
151 	}
152     }
153 
154     if (type == 0)
155     {
156 	if (pitem && (utt = item_utt(pitem)))
157 	    ff = feat_val(utt->ffunctions,tk);
158 	else
159 	    ff = NULL;
160 	void_v = NULL;
161 	if (!ff)
162 	    void_v = (void *)item_feat(pitem,tk);
163 	else if (pitem)
164 	{
165 	    ffunc = val_ffunc(ff);
166 	    void_v = (void *)(*ffunc)(pitem);
167 	}
168 	if (void_v == NULL)
169         {
170 #if 0
171             if (pitem)
172                 printf("awb_debug didn't find %s in %s\n",tk,
173                        get_param_string(pitem->contents->features,"name","noname"));
174             else
175             {
176                 if (cst_streq("gpos",tk))
177                     printf("awb_debug2\n");
178                 printf("awb_debug didn't find %s %s\n",tk,featpath);
179             }
180 #endif
181 	    void_v = (void *)&ffeature_default_val;
182         }
183     }
184     else
185 	void_v = (void *)pitem;
186 
187     return void_v;
188 }
189 
ff_register(cst_features * ffunctions,const char * name,cst_ffunction f)190 void ff_register(cst_features *ffunctions, const char *name, cst_ffunction f)
191 {
192     /* Register features functions */
193 
194 #if 0
195     if (feat_present(ffunctions, name))
196 	cst_errmsg("warning: ffunction %s redefined\n", name);
197 #endif
198     feat_set(ffunctions, name, ffunc_val(f));
199 }
200 
ff_unregister(cst_features * ffunctions,const char * name)201 void ff_unregister(cst_features *ffunctions, const char *name)
202 {
203     feat_remove(ffunctions, name);
204 }
205