link-grammar-5.8.0/link-grammar/tokenize/wg-display.c
/**
 *  Generate the wordgraph in dot(1) format, for debug.
 */
Generate the wordgraph in dot(1) format, for debug.
Generate the wordgraph in dot ( 1 ) format for debug .
static dyn_str *wordgraph2dot(Sentence sent, unsigned int mode, const char *modestr)
{
	const Gword *w;
	Gword	**wp;
	dyn_str *wgd = dyn_str_new(); 
	char nn[2*sizeof(char *) + 2 + 2 + 1]; 
	UNREACHABLE(NULL == sent->wordgraph->chain_next);
	append_string(wgd, "# Mode: %s\n", modestr);
	dyn_strcat(wgd, "digraph G {\nsize =\"30,20\";\nrankdir=LR;\n");
	if ((mode & (WGR_SUB)) && !(mode & WGR_COMPACT))
		dyn_strcat(wgd, "newrank=true;\n");
	if (mode & WGR_LEGEND) wordgraph_legend(wgd, mode);
	append_string(wgd, "\"%p\" [shape=box,style=filled,color=\".7 .3 1.0\"];\n",
	              sent->wordgraph);
	for (w = sent->wordgraph; w; w = w->chain_next)
	{
		bool show_node;
		if (!(mode & WGR_UNSPLIT) && (MT_INFRASTRUCTURE != w->morpheme_type))
		{
			Gword *wu;
			show_node = false;
			for (wu = sent->wordgraph; wu; wu = wu->chain_next)
			{
				if (NULL != wu->next)
				{
					for (wp = wu->next; *wp; wp++)
					{
						if (w == *wp)
						{
							show_node = true;
							break;
						}
					}
				}
			}
			if (!show_node) continue;
		}
		snprintf(nn, sizeof(nn), "\"%p\"", w);
		append_string(wgd, "%s [label=\"%s\\n(%s)\\n%s\"];\n", nn,
			wlabel(sent, w), gword_status(sent, w), gword_morpheme(sent, w));
		if (!(mode & WGR_DBGLABEL))
		{
			append_string(wgd, "%s [xlabel=\"%zu",
							  nn, w->node_num);
		}
		else
		{
			append_string(wgd, "%s [xlabel=\"%zu\\n%s",
							  nn, w->node_num, w->label);
		}
		if (mode & WGR_DOTDEBUG)
			append_string(wgd, "\\n%p-%s", w, wlabel(sent, w));
		dyn_strcat(wgd, "\"];\n");
		if (NULL != w->next)
		{
			for (wp = w->next; *wp; wp++)
			{
				append_string(wgd, "%s->\"%p\" [label=next color=red];\n",
				              nn, *wp);
			}
		}
		if (mode & WGR_PREV)
		{
			if (NULL != w->prev)
			{
				for (wp = w->prev; *wp; wp++)
				{
					append_string(wgd, "%s->\"%p\" [label=prev color=blue];\n",
					              nn, *wp);
				}
			}
		}
		if (mode & WGR_UNSPLIT)
		{
			if (!(mode & WGR_SUB) && (NULL != w->unsplit_word))
			{
				append_string(wgd, "%s->\"%p\" [label=unsplit];\n",
				              nn, w->unsplit_word);
			}
		}
	}
	if (mode & WGR_SUB)
	{
		const Gword *old_unsplit = NULL;
		for (w = sent->wordgraph; w; w = w->chain_next)
		{
			if (NULL != w->unsplit_word)
			{
				if (w->unsplit_word != old_unsplit)
				{
					if (NULL != old_unsplit) dyn_strcat(wgd, "}\n");
					append_string(wgd, "subgraph \"cluster-%p\" {", w->unsplit_word);
					append_string(wgd, "label=\"%zu %s\"; \n",
						w->unsplit_word->node_num, wlabel(sent, w->unsplit_word));
					old_unsplit = w->unsplit_word;
				}
				snprintf(nn, sizeof(nn), "\"%p\"", w);
				if (strstr(dyn_str_value(wgd), nn))
					append_string(wgd, "\"%p\"; ", w);
			}
		}
		dyn_strcat(wgd, "}\n");
	}
	else
	{
#ifdef WGR_SHOW_TERMINATOR_AT_LHS 
		const Gword *terminating_node = NULL;
#endif
		dyn_strcat(wgd, "{rank=same; ");
		for (w = sent->wordgraph->chain_next; w; w = w->chain_next)
		{
			snprintf(nn, sizeof(nn), "\"%p\"", w);
			if (IS_SENTENCE_WORD(sent, w) &&
			    ((mode & WGR_UNSPLIT) || strstr(dyn_str_value(wgd), nn)))
			{
				append_string(wgd, "%s; ", nn);
			}
#ifdef WGR_SHOW_TERMINATOR_AT_LHS
			if (NULL == w->next) terminating_node = w;
#endif
		}
		dyn_strcat(wgd, "}\n");
#ifdef WGR_SHOW_TERMINATOR_AT_LHS
		if (terminating_node)
			append_string(wgd, "{rank=sink; \"%p\"}\n", terminating_node);
#endif
	}
	dyn_strcat(wgd, "\n}\n");
	return wgd;
}
static dyn_str * wordgraph2dot ( Sentence sent , unsigned int mode , const char * modestr ) { const Gword * w ; Gword * * wp ; dyn_str * wgd = dyn_str_new ( ) ; char nn [ 2 * sizeof ( char * ) + 2 + 2 + 1 ] ; UNREACHABLE ( NULL == sent -> wordgraph -> chain_next ) ; append_string ( wgd , " \n " , modestr ) ; dyn_strcat ( wgd , " \n \" \" \n \n " ) ; if ( ( mode & ( WGR_SUB ) ) && ! ( mode & WGR_COMPACT ) ) dyn_strcat ( wgd , " \n " ) ; if ( mode & WGR_LEGEND ) wordgraph_legend ( wgd , mode ) ; append_string ( wgd , " \" \" \" \" \n " , sent -> wordgraph ) ; for ( w = sent -> wordgraph ; w ; w = w -> chain_next ) { bool show_node ; if ( ! ( mode & WGR_UNSPLIT ) && ( MT_INFRASTRUCTURE != w -> morpheme_type ) ) { Gword * wu ; show_node = false ; for ( wu = sent -> wordgraph ; wu ; wu = wu -> chain_next ) { if ( NULL != wu -> next ) { for ( wp = wu -> next ; * wp ; wp ++ ) { if ( w == * wp ) { show_node = true ; break ; } } } } if ( ! show_node ) continue ; } snprintf ( nn , sizeof ( nn ) , " \" \" " , w ) ; append_string ( wgd , " \" \\ \\ \" \n " , nn , wlabel ( sent , w ) , gword_status ( sent , w ) , gword_morpheme ( sent , w ) ) ; if ( ! ( mode & WGR_DBGLABEL ) ) { append_string ( wgd , " \" " , nn , w -> node_num ) ; } else { append_string ( wgd , " \" \\ " , nn , w -> node_num , w -> label ) ; } if ( mode & WGR_DOTDEBUG ) append_string ( wgd , " \\ " , w , wlabel ( sent , w ) ) ; dyn_strcat ( wgd , " \" \n " ) ; if ( NULL != w -> next ) { for ( wp = w -> next ; * wp ; wp ++ ) { append_string ( wgd , " \" \" \n " , nn , * wp ) ; } } if ( mode & WGR_PREV ) { if ( NULL != w -> prev ) { for ( wp = w -> prev ; * wp ; wp ++ ) { append_string ( wgd , " \" \" \n " , nn , * wp ) ; } } } if ( mode & WGR_UNSPLIT ) { if ( ! ( mode & WGR_SUB ) && ( NULL != w -> unsplit_word ) ) { append_string ( wgd , " \" \" \n " , nn , w -> unsplit_word ) ; } } } if ( mode & WGR_SUB ) { const Gword * old_unsplit = NULL ; for ( w = sent -> wordgraph ; w ; w = w -> chain_next ) { if ( NULL != w -> unsplit_word ) { if ( w -> unsplit_word != old_unsplit ) { if ( NULL != old_unsplit ) dyn_strcat ( wgd , " \n " ) ; append_string ( wgd , " \" \" " , w -> unsplit_word ) ; append_string ( wgd , " \" \" \n " , w -> unsplit_word -> node_num , wlabel ( sent , w -> unsplit_word ) ) ; old_unsplit = w -> unsplit_word ; } snprintf ( nn , sizeof ( nn ) , " \" \" " , w ) ; if ( strstr ( dyn_str_value ( wgd ) , nn ) ) append_string ( wgd , " \" \" " , w ) ; } } dyn_strcat ( wgd , " \n " ) ; } else { #ifdef WGR_SHOW_TERMINATOR_AT_LHS const Gword * terminating_node = NULL ; #endif dyn_strcat ( wgd , " " ) ; for ( w = sent -> wordgraph -> chain_next ; w ; w = w -> chain_next ) { snprintf ( nn , sizeof ( nn ) , " \" \" " , w ) ; if ( IS_SENTENCE_WORD ( sent , w ) && ( ( mode & WGR_UNSPLIT ) || strstr ( dyn_str_value ( wgd ) , nn ) ) ) { append_string ( wgd , " " , nn ) ; } #ifdef WGR_SHOW_TERMINATOR_AT_LHS if ( NULL == w -> next ) terminating_node = w ; #endif } dyn_strcat ( wgd , " \n " ) ; #ifdef WGR_SHOW_TERMINATOR_AT_LHS if ( terminating_node ) append_string ( wgd , " \" \" \n " , terminating_node ) ; #endif } dyn_strcat ( wgd , " \n \n " ) ; return wgd ; }
Generate the wordgraph in dot(1) format, for debug.
Generate the wordgraph in dot ( 1 ) format for debug .
/* the wordgraph in dot representation */ /* \"%p\" node name: "0x..."+NUL*/ /* This function is called only if we have a wordgraph, in which case
	 * chain_next is non-NULL. So stop static analyzers to complain that
	 * it can be possibly NULL. */ /* In this mode nodes that are only unsplit_word are not shown. */ /* Subword node format:
		 *                     +------------------+
		 *                     +                  +
		 *                     +    w->subword    +
		 *                     +    (w->flags)    +
		 *                     + w->morpheme_type +
		 *                     +                  +
		 *                     +------------------+
		 *          w->node_num  } <- external node label
		 *           w->label    }
		 *
		 * The flags and morpheme type are printed symbolically.
		 * The node_num field is the ordinal number of word creation.
		 * The label shows the code positions that created the subword.
		 * The external node label may appear at other positions near the node.
		 *
		 * FIXME: Use HTML labels.
		 */ /* For debugging this function: display also hex node names. */ /* not defined - not useful */