• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /macosx-10.9.5/tcl-102/tcl_ext/tcllib/tcllib/modules/pt/tests/data/ok/peg_cparam-critcl/
1## -*- tcl -*-
2##
3## Critcl-based C/PARAM implementation of the parsing
4## expression grammar
5##
6##	TEMPLATE
7##
8## Generated from file	TEST
9##            for user  unknown
10##
11# # ## ### ##### ######## ############# #####################
12## Requirements
13
14package require Tcl 8.4
15package require critcl
16# @sak notprovided PACKAGE
17package provide    PACKAGE 1
18
19# Note: The implementation of the PARAM virtual machine
20#       underlying the C/PARAM code used below is inlined
21#       into the generated parser, allowing for direct access
22#       and manipulation of the RDE state, instead of having
23#       to dispatch through the Tcl interpreter.
24
25# # ## ### ##### ######## ############# #####################
26##
27
28namespace eval ::PARSER {
29    # # ## ### ##### ######## ############# #####################
30    ## Supporting code for the main command.
31
32    catch {
33	critcl::cheaders -g
34	critcl::debug memory symbols
35    }
36
37    # # ## ### ###### ######## #############
38    ## RDE runtime, inlined, and made static.
39
40    # This is the C code for the RDE, i.e. the implementation
41    # of pt::rde. Only the low-level engine is imported, the
42    # Tcl interface layer is ignored.  This generated parser
43    # provides its own layer for that.
44
45    critcl::ccode {
46	/* -*- c -*- */
47
48	#include <string.h>
49	#define SCOPE static
50
51#line 1 "rde_critcl/util.h"
52
53	#ifndef _RDE_UTIL_H
54	#define _RDE_UTIL_H 1
55	#ifndef SCOPE
56	#define SCOPE
57	#endif
58	#define ALLOC(type)    (type *) ckalloc (sizeof (type))
59	#define NALLOC(n,type) (type *) ckalloc ((n) * sizeof (type))
60	#undef  RDE_DEBUG
61	#define RDE_DEBUG 1
62	#undef  RDE_TRACE
63	#ifdef RDE_DEBUG
64	#define STOPAFTER(x) { static int count = (x); count --; if (!count) { Tcl_Panic ("stop"); } }
65	#define XSTR(x) #x
66	#define STR(x) XSTR(x)
67	#define RANGEOK(i,n) ((0 <= (i)) && (i < (n)))
68	#define ASSERT(x,msg) if (!(x)) { Tcl_Panic (msg " (" #x "), in file " __FILE__ " @line " STR(__LINE__));}
69	#define ASSERT_BOUNDS(i,n) ASSERT (RANGEOK(i,n),"array index out of bounds: " STR(i) " >= " STR(n))
70	#else
71	#define STOPAFTER(x)
72	#define ASSERT(x,msg)
73	#define ASSERT_BOUNDS(i,n)
74	#endif
75	#ifdef RDE_TRACE
76	SCOPE void trace_enter (const char* fun);
77	SCOPE void trace_return (const char *pat, ...);
78	SCOPE void trace_printf (const char *pat, ...);
79	#define ENTER(fun)          trace_enter (fun)
80	#define RETURN(format,x)    trace_return (format,x) ; return x
81	#define RETURNVOID          trace_return ("%s","(void)") ; return
82	#define TRACE0(x)           trace_printf0 x
83	#define TRACE(x)            trace_printf x
84	#else
85	#define ENTER(fun)
86	#define RETURN(f,x) return x
87	#define RETURNVOID  return
88	#define TRACE0(x)
89	#define TRACE(x)
90	#endif
91	#endif 
92	
93
94#line 1 "rde_critcl/stack.h"
95
96	#ifndef _RDE_DS_STACK_H
97	#define _RDE_DS_STACK_H 1
98	typedef void (*RDE_STACK_CELL_FREE) (void* cell);
99	typedef struct RDE_STACK_* RDE_STACK;
100	static const int RDE_STACK_INITIAL_SIZE = 256;
101	#endif 
102	
103
104#line 1 "rde_critcl/tc.h"
105
106	#ifndef _RDE_DS_TC_H
107	#define _RDE_DS_TC_H 1
108	typedef struct RDE_TC_* RDE_TC;
109	#endif 
110	
111
112#line 1 "rde_critcl/param.h"
113
114	#ifndef _RDE_DS_PARAM_H
115	#define _RDE_DS_PARAM_H 1
116	typedef struct RDE_PARAM_* RDE_PARAM;
117	typedef struct ERROR_STATE {
118	    int       refCount;
119	    long int  loc;
120	    RDE_STACK msg; 
121	} ERROR_STATE;
122	typedef struct NC_STATE {
123	    long int     CL;
124	    long int     ST;
125	    Tcl_Obj*     SV;
126	    ERROR_STATE* ER;
127	} NC_STATE;
128	#endif 
129	
130
131#line 1 "rde_critcl/util.c"
132
133	#ifdef RDE_TRACE
134	typedef struct F_STACK {
135	    const char*     str;
136	    struct F_STACK* down;
137	} F_STACK;
138	static F_STACK* top   = 0;
139	static int      level = 0;
140	static void
141	push (const char* str)
142	{
143	    F_STACK* new = ALLOC (F_STACK);
144	    new->str = str;
145	    new->down = top;
146	    top = new;
147	    level += 4;
148	}
149	static void
150	pop (void)
151	{
152	    F_STACK* next = top->down;
153	    level -= 4;
154	    ckfree ((char*)top);
155	    top = next;
156	}
157	static void
158	indent (void)
159	{
160	    int i;
161	    for (i = 0; i < level; i++) {
162		fwrite(" ", 1, 1, stdout);
163		fflush           (stdout);
164	    }
165	    if (top) {
166		fwrite(top->str, 1, strlen(top->str), stdout);
167		fflush                               (stdout);
168	    }
169	    fwrite(" ", 1, 1, stdout);
170	    fflush           (stdout);
171	}
172	SCOPE void
173	trace_enter (const char* fun)
174	{
175	    push (fun);
176	    indent();
177	    fwrite("ENTER\n", 1, 6, stdout);
178	    fflush                 (stdout);
179	}
180	static char msg [1024*1024];
181	SCOPE void
182	trace_return (const char *pat, ...)
183	{
184	    int len;
185	    va_list args;
186	    indent();
187	    fwrite("RETURN = ", 1, 9, stdout);
188	    fflush                   (stdout);
189	    va_start(args, pat);
190	    len = vsprintf(msg, pat, args);
191	    va_end(args);
192	    msg[len++] = '\n';
193	    msg[len] = '\0';
194	    fwrite(msg, 1, len, stdout);
195	    fflush             (stdout);
196	    pop();
197	}
198	SCOPE void
199	trace_printf (const char *pat, ...)
200	{
201	    int len;
202	    va_list args;
203	    indent();
204	    va_start(args, pat);
205	    len = vsprintf(msg, pat, args);
206	    va_end(args);
207	    msg[len++] = '\n';
208	    msg[len] = '\0';
209	    fwrite(msg, 1, len, stdout);
210	    fflush             (stdout);
211	}
212	SCOPE void
213	trace_printf0 (const char *pat, ...)
214	{
215	    int len;
216	    va_list args;
217	    va_start(args, pat);
218	    len = vsprintf(msg, pat, args);
219	    va_end(args);
220	    msg[len++] = '\n';
221	    msg[len] = '\0';
222	    fwrite(msg, 1, len, stdout);
223	    fflush             (stdout);
224	}
225	#endif
226	
227
228#line 1 "rde_critcl/stack.c"
229
230	typedef struct RDE_STACK_ {
231	    long int            max;   
232	    long int            top;   
233	    RDE_STACK_CELL_FREE freeCellProc; 
234	    void**              cell;  
235	} RDE_STACK_;
236	
237	SCOPE RDE_STACK
238	rde_stack_new (RDE_STACK_CELL_FREE freeCellProc)
239	{
240	    RDE_STACK s = ALLOC (RDE_STACK_);
241	    s->cell = NALLOC (RDE_STACK_INITIAL_SIZE, void*);
242	    s->max  = RDE_STACK_INITIAL_SIZE;
243	    s->top  = 0;
244	    s->freeCellProc = freeCellProc;
245	    return s;
246	}
247	SCOPE void
248	rde_stack_del (RDE_STACK s)
249	{
250	    if (s->freeCellProc && s->top) {
251		long int i;
252		for (i=0; i < s->top; i++) {
253		    ASSERT_BOUNDS(i,s->max);
254		    s->freeCellProc ( s->cell [i] );
255		}
256	    }
257	    ckfree ((char*) s->cell);
258	    ckfree ((char*) s);
259	}
260	SCOPE void
261	rde_stack_push (RDE_STACK s, void* item)
262	{
263	    if (s->top >= s->max) {
264		long int new  = s->max ? (2 * s->max) : RDE_STACK_INITIAL_SIZE;
265		void**   cell = (void**) ckrealloc ((char*) s->cell, new * sizeof(void*));
266		ASSERT (cell,"Memory allocation failure for RDE stack");
267		s->max  = new;
268		s->cell = cell;
269	    }
270	    ASSERT_BOUNDS(s->top,s->max);
271	    s->cell [s->top] = item;
272	    s->top ++;
273	}
274	SCOPE void*
275	rde_stack_top (RDE_STACK s)
276	{
277	    ASSERT_BOUNDS(s->top-1,s->max);
278	    return s->cell [s->top - 1];
279	}
280	SCOPE void
281	rde_stack_pop (RDE_STACK s, long int n)
282	{
283	    ASSERT (n >= 0, "Bad pop count");
284	    if (n == 0) return;
285	    if (s->freeCellProc) {
286		while (n) {
287		    s->top --;
288		    ASSERT_BOUNDS(s->top,s->max);
289		    s->freeCellProc ( s->cell [s->top] );
290		    n --;
291		}
292	    } else {
293		s->top -= n;
294	    }
295	}
296	SCOPE void
297	rde_stack_trim (RDE_STACK s, long int n)
298	{
299	    ASSERT (n >= 0, "Bad trimsize");
300	    if (s->freeCellProc) {
301		while (s->top > n) {
302		    s->top --;
303		    ASSERT_BOUNDS(s->top,s->max);
304		    s->freeCellProc ( s->cell [s->top] );
305		}
306	    } else {
307		s->top = n;
308	    }
309	}
310	SCOPE void
311	rde_stack_drop (RDE_STACK s, long int n)
312	{
313	    ASSERT (n >= 0, "Bad pop count");
314	    if (n == 0) return;
315	    s->top -= n;
316	}
317	SCOPE void
318	rde_stack_move (RDE_STACK dst, RDE_STACK src)
319	{
320	    ASSERT (dst->freeCellProc == src->freeCellProc, "Ownership mismatch");
321	    
322	    while (src->top > 0) {
323		src->top --;
324		ASSERT_BOUNDS(src->top,src->max);
325		rde_stack_push (dst, src->cell [src->top] );
326	    }
327	}
328	SCOPE void
329	rde_stack_get (RDE_STACK s, long int* cn, void*** cc)
330	{
331	    *cn = s->top;
332	    *cc = s->cell;
333	}
334	SCOPE long int
335	rde_stack_size (RDE_STACK s)
336	{
337	    return s->top;
338	}
339	
340
341#line 1 "rde_critcl/tc.c"
342
343	typedef struct RDE_TC_ {
344	    int       max;   
345	    int       num;   
346	    char*     str;   
347	    RDE_STACK off;   
348	} RDE_TC_;
349	
350	SCOPE RDE_TC
351	rde_tc_new (void)
352	{
353	    RDE_TC tc = ALLOC (RDE_TC_);
354	    tc->max   = RDE_STACK_INITIAL_SIZE;
355	    tc->num   = 0;
356	    tc->str   = NALLOC (RDE_STACK_INITIAL_SIZE, char);
357	    tc->off   = rde_stack_new (NULL);
358	    return tc;
359	}
360	SCOPE void
361	rde_tc_del (RDE_TC tc)
362	{
363	    rde_stack_del (tc->off);
364	    ckfree (tc->str);
365	    ckfree ((char*) tc);
366	}
367	SCOPE long int
368	rde_tc_size (RDE_TC tc)
369	{
370	    return rde_stack_size (tc->off);
371	}
372	SCOPE void
373	rde_tc_clear (RDE_TC tc)
374	{
375	    tc->num   = 0;
376	    rde_stack_trim (tc->off,  0);
377	}
378	SCOPE char*
379	rde_tc_append (RDE_TC tc, char* string, long int len)
380	{
381	    long int base = tc->num;
382	    long int off  = tc->num;
383	    char* ch;
384	    int clen;
385	    Tcl_UniChar uni;
386	    if (len < 0) {
387		len = strlen (ch);
388	    }
389	    
390	    if ((tc->num + len) >= tc->max) {
391		int   new = len + (tc->max ? (2 * tc->max) : RDE_STACK_INITIAL_SIZE);
392		char* str = ckrealloc (tc->str, new * sizeof(char));
393		ASSERT (str,"Memory allocation failure for token character array");
394		tc->max = new;
395		tc->str = str;
396	    }
397	    tc->num += len;
398	    ASSERT_BOUNDS(tc->num,tc->max);
399	    ASSERT_BOUNDS(off,tc->max);
400	    ASSERT_BOUNDS(off+len-1,tc->max);
401	    ASSERT_BOUNDS(off+len-1,tc->num);
402	    memcpy (tc->str + off, string, len);
403	    
404	    ch = string;
405	    while (ch < (string + len)) {
406		ASSERT_BOUNDS(off,tc->num);
407		rde_stack_push (tc->off,  (void*) off);
408		clen = Tcl_UtfToUniChar (ch, &uni);
409		off += clen;
410		ch  += clen;
411	    }
412	    return tc->str + base;
413	}
414	SCOPE void
415	rde_tc_get (RDE_TC tc, int at, char** ch, long int* len)
416	{
417	    long int  oc, off, top, end;
418	    long int* ov;
419	    rde_stack_get (tc->off, &oc, (void***) &ov);
420	    ASSERT_BOUNDS(at,oc);
421	    off = ov [at];
422	    if ((at+1) == oc) {
423		end = tc->num;
424	    } else {
425		end = ov [at+1];
426	    }
427	    TRACE (("rde_tc_get (RDE_TC %p, @ %d) => %d.[%d ... %d]/%d",tc,at,end-off,off,end-1,tc->num));
428	    ASSERT_BOUNDS(off,tc->num);
429	    ASSERT_BOUNDS(end-1,tc->num);
430	    *ch = tc->str + off;
431	    *len = end - off;
432	}
433	SCOPE void
434	rde_tc_get_s (RDE_TC tc, int at, int last, char** ch, long int* len)
435	{
436	    long int  oc, off, top, end;
437	    long int* ov;
438	    rde_stack_get (tc->off, &oc, (void***) &ov);
439	    ASSERT_BOUNDS(at,oc);
440	    ASSERT_BOUNDS(last,oc);
441	    off = ov [at];
442	    if ((last+1) == oc) {
443		end = tc->num;
444	    } else {
445		end = ov [last+1];
446	    }
447	    TRACE (("rde_tc_get_s (RDE_TC %p, @ %d .. %d) => %d.[%d ... %d]/%d",tc,at,last,end-off,off,end-1,tc->num));
448	    ASSERT_BOUNDS(off,tc->num);
449	    ASSERT_BOUNDS(end-1,tc->num);
450	    *ch = tc->str + off;
451	    *len = end - off;
452	}
453	
454
455#line 1 "rde_critcl/param.c"
456
457	typedef struct RDE_PARAM_ {
458	    Tcl_Channel   IN;
459	    Tcl_Obj*      readbuf;
460	    char*         CC; 
461	    long int      CC_len;
462	    RDE_TC        TC;
463	    long int      CL;
464	    RDE_STACK     LS; 
465	    ERROR_STATE*  ER;
466	    RDE_STACK     ES; 
467	    long int      ST;
468	    Tcl_Obj*      SV;
469	    Tcl_HashTable NC;
470	    
471	    RDE_STACK    ast  ; 
472	    RDE_STACK    mark ; 
473	    
474	    long int numstr; 
475	    char**  string;
476	    
477	    ClientData clientData;
478	} RDE_PARAM_;
479	typedef int (*UniCharClass) (int);
480	typedef enum test_class_id {
481	    tc_alnum,
482	    tc_alpha,
483	    tc_ascii,
484	    tc_ddigit,
485	    tc_digit,
486	    tc_graph,
487	    tc_lower,
488	    tc_printable,
489	    tc_punct,
490	    tc_space,
491	    tc_upper,
492	    tc_wordchar,
493	    tc_xdigit
494	} test_class_id;
495	static void ast_node_free    (void* n);
496	static void error_state_free (void* es);
497	static void error_set        (RDE_PARAM p, int s);
498	static void nc_clear         (RDE_PARAM p);
499	static int UniCharIsAscii    (int character);
500	static int UniCharIsHexDigit (int character);
501	static int UniCharIsDecDigit (int character);
502	static void test_class (RDE_PARAM p, UniCharClass class, test_class_id id);
503	static int  er_int_compare (const void* a, const void* b);
504	#define SV_INIT(p)             \
505	    p->SV = NULL; \
506	    TRACE (("SV_INIT (%p => %p)", (p), (p)->SV))
507	#define SV_SET(p,newsv)             \
508	    if (((p)->SV) != (newsv)) { \
509	        TRACE (("SV_CLEAR/set (%p => %p)", (p), (p)->SV)); \
510	        if ((p)->SV) {                  \
511		    Tcl_DecrRefCount ((p)->SV); \
512	        }				    \
513	        (p)->SV = (newsv);		    \
514	        TRACE (("SV_SET       (%p => %p)", (p), (p)->SV)); \
515	        if ((p)->SV) {                  \
516		    Tcl_IncrRefCount ((p)->SV); \
517	        } \
518	    }
519	#define SV_CLEAR(p)                 \
520	    TRACE (("SV_CLEAR (%p => %p)", (p), (p)->SV)); \
521	    if ((p)->SV) {                  \
522		Tcl_DecrRefCount ((p)->SV); \
523	    }				    \
524	    (p)->SV = NULL
525	#define ER_INIT(p)             \
526	    p->ER = NULL; \
527	    TRACE (("ER_INIT (%p => %p)", (p), (p)->ER))
528	#define ER_CLEAR(p)             \
529	    error_state_free ((p)->ER);	\
530	    (p)->ER = NULL
531	SCOPE RDE_PARAM
532	rde_param_new (long int nstr, char** strings)
533	{
534	    RDE_PARAM p;
535	    ENTER ("rde_param_new");
536	    TRACE (("\tINT %d strings @ %p", nstr, strings));
537	    p = ALLOC (RDE_PARAM_);
538	    p->numstr = nstr;
539	    p->string = strings;
540	    p->readbuf = Tcl_NewObj ();
541	    Tcl_IncrRefCount (p->readbuf);
542	    TRACE (("\tTcl_Obj* readbuf %p used %d", p->readbuf,p->readbuf->refCount));
543	    Tcl_InitHashTable (&p->NC, TCL_ONE_WORD_KEYS);
544	    p->IN   = NULL;
545	    p->CL   = -1;
546	    p->ST   = 0;
547	    ER_INIT (p);
548	    SV_INIT (p);
549	    p->CC   = NULL;
550	    p->CC_len = 0;
551	    p->TC   = rde_tc_new ();
552	    p->ES   = rde_stack_new (error_state_free);
553	    p->LS   = rde_stack_new (NULL);
554	    p->ast  = rde_stack_new (ast_node_free);
555	    p->mark = rde_stack_new (NULL);
556	    RETURN ("%p", p);
557	}
558	SCOPE void 
559	rde_param_del (RDE_PARAM p)
560	{
561	    ENTER ("rde_param_del");
562	    TRACE (("RDE_PARAM %p",p));
563	    ER_CLEAR (p);                 TRACE (("\ter_clear"));
564	    SV_CLEAR (p);                 TRACE (("\tsv_clear"));
565	    nc_clear (p);                 TRACE (("\tnc_clear"));
566	    Tcl_DeleteHashTable (&p->NC); TRACE (("\tnc hashtable delete"));
567	    rde_tc_del    (p->TC);        TRACE (("\ttc clear"));
568	    rde_stack_del (p->ES);        TRACE (("\tes clear"));
569	    rde_stack_del (p->LS);        TRACE (("\tls clear"));
570	    rde_stack_del (p->ast);       TRACE (("\tast clear"));
571	    rde_stack_del (p->mark);      TRACE (("\tmark clear"));
572	    TRACE (("\tTcl_Obj* readbuf %p used %d", p->readbuf,p->readbuf->refCount));
573	    Tcl_DecrRefCount (p->readbuf);
574	    ckfree ((char*) p);
575	    RETURNVOID;
576	}
577	SCOPE void 
578	rde_param_reset (RDE_PARAM p, Tcl_Channel chan)
579	{
580	    ENTER ("rde_param_reset");
581	    TRACE (("RDE_PARAM   %p",p));
582	    TRACE (("Tcl_Channel %p",chan));
583	    p->IN  = chan;
584	    p->CL  = -1;
585	    p->ST  = 0;
586	    p->CC  = NULL;
587	    p->CC_len = 0;
588	    ER_CLEAR (p);
589	    SV_CLEAR (p);
590	    nc_clear (p);
591	    rde_tc_clear   (p->TC);
592	    rde_stack_trim (p->ES,   0);
593	    rde_stack_trim (p->LS,   0);
594	    rde_stack_trim (p->ast,  0);
595	    rde_stack_trim (p->mark, 0);
596	    TRACE (("\tTcl_Obj* readbuf %p used %d", p->readbuf,p->readbuf->refCount));
597	    RETURNVOID;
598	}
599	SCOPE void
600	rde_param_update_strings (RDE_PARAM p, long int nstr, char** strings)
601	{
602	    ENTER ("rde_param_update_strings");
603	    TRACE (("RDE_PARAM %p", p));
604	    TRACE (("INT       %d strings", nstr));
605	    p->numstr = nstr;
606	    p->string = strings;
607	    RETURNVOID;
608	}
609	SCOPE void
610	rde_param_data (RDE_PARAM p, char* buf, long int len)
611	{
612	    (void) rde_tc_append (p->TC, buf, len);
613	}
614	SCOPE void
615	rde_param_clientdata (RDE_PARAM p, ClientData clientData)
616	{
617	    p->clientData = clientData;
618	}
619	static void
620	nc_clear (RDE_PARAM p)
621	{
622	    Tcl_HashSearch hs;
623	    Tcl_HashEntry* he;
624	    Tcl_HashTable* tablePtr;
625	    for(he = Tcl_FirstHashEntry(&p->NC, &hs);
626		he != NULL;
627		he = Tcl_FirstHashEntry(&p->NC, &hs)) {
628		Tcl_HashSearch hsc;
629		Tcl_HashEntry* hec;
630		tablePtr = (Tcl_HashTable*) Tcl_GetHashValue (he);
631		for(hec = Tcl_FirstHashEntry(tablePtr, &hsc);
632		    hec != NULL;
633		    hec = Tcl_NextHashEntry(&hsc)) {
634		    NC_STATE* scs = Tcl_GetHashValue (hec);
635		    error_state_free (scs->ER);
636		    if (scs->SV) { Tcl_DecrRefCount (scs->SV); }
637		    ckfree ((char*) scs);
638		}
639		Tcl_DeleteHashTable (tablePtr);
640		ckfree ((char*) tablePtr);
641		Tcl_DeleteHashEntry (he);
642	    }
643	}
644	SCOPE ClientData
645	rde_param_query_clientdata (RDE_PARAM p)
646	{
647	    return p->clientData;
648	}
649	SCOPE void
650	rde_param_query_amark (RDE_PARAM p, long int* mc, long int** mv)
651	{
652	    rde_stack_get (p->mark, mc, (void***) mv);
653	}
654	SCOPE void
655	rde_param_query_ast (RDE_PARAM p, long int* ac, Tcl_Obj*** av)
656	{
657	    rde_stack_get (p->ast, ac, (void***) av);
658	}
659	SCOPE const char*
660	rde_param_query_in (RDE_PARAM p)
661	{
662	    return p->IN
663		? Tcl_GetChannelName (p->IN)
664		: "";
665	}
666	SCOPE const char*
667	rde_param_query_cc (RDE_PARAM p, long int* len)
668	{
669	    *len = p->CC_len;
670	    return p->CC;
671	}
672	SCOPE int
673	rde_param_query_cl (RDE_PARAM p)
674	{
675	    return p->CL;
676	}
677	SCOPE const ERROR_STATE*
678	rde_param_query_er (RDE_PARAM p)
679	{
680	    return p->ER;
681	}
682	SCOPE Tcl_Obj*
683	rde_param_query_er_tcl (RDE_PARAM p, const ERROR_STATE* er)
684	{
685	    Tcl_Obj* res;
686	    if (!er) {
687		
688		res = Tcl_NewStringObj ("", 0);
689	    } else {
690		Tcl_Obj* ov [2];
691		Tcl_Obj** mov;
692		long int  mc, i, j;
693		long int* mv;
694		int lastid;
695		const char* msg;
696		rde_stack_get (er->msg, &mc, (void***) &mv);
697		
698		qsort (mv, mc, sizeof (long int), er_int_compare);
699		
700		mov = NALLOC (mc, Tcl_Obj*);
701		lastid = -1;
702		for (i=0, j=0; i < mc; i++) {
703		    ASSERT_BOUNDS (i,mc);
704		    if (mv [i] == lastid) continue;
705		    lastid = mv [i];
706		    ASSERT_BOUNDS(mv[i],p->numstr);
707		    msg = p->string [mv[i]]; 
708		    ASSERT_BOUNDS (j,mc);
709		    mov [j] = Tcl_NewStringObj (msg, -1);
710		    j++;
711		}
712		
713		ov [0] = Tcl_NewIntObj  (er->loc);
714		ov [1] = Tcl_NewListObj (j, mov);
715		res = Tcl_NewListObj (2, ov);
716		ckfree ((char*) mov);
717	    }
718	    return res;
719	}
720	SCOPE void
721	rde_param_query_es (RDE_PARAM p, long int* ec, ERROR_STATE*** ev)
722	{
723	    rde_stack_get (p->ES, ec, (void***) ev);
724	}
725	SCOPE void
726	rde_param_query_ls (RDE_PARAM p, long int* lc, long int** lv)
727	{
728	    rde_stack_get (p->LS, lc, (void***) lv);
729	}
730	SCOPE Tcl_HashTable*
731	rde_param_query_nc (RDE_PARAM p)
732	{
733	    return &p->NC;
734	}
735	SCOPE int
736	rde_param_query_st (RDE_PARAM p)
737	{
738	    return p->ST;
739	}
740	SCOPE Tcl_Obj*
741	rde_param_query_sv (RDE_PARAM p)
742	{
743	    TRACE (("SV_QUERY %p => (%p)", (p), (p)->SV)); \
744	    return p->SV;
745	}
746	SCOPE long int
747	rde_param_query_tc_size (RDE_PARAM p)
748	{
749	    return rde_tc_size (p->TC);
750	}
751	SCOPE void
752	rde_param_query_tc_get_s (RDE_PARAM p, long int at, long int last, char** ch, long int* len)
753	{
754	    rde_tc_get_s (p->TC, at, last, ch, len);
755	}
756	SCOPE const char*
757	rde_param_query_string (RDE_PARAM p, long int id)
758	{
759	    TRACE (("rde_param_query_string (RDE_PARAM %p, %d/%d)", p, id, p->numstr));
760	    ASSERT_BOUNDS(id,p->numstr);
761	    return p->string [id];
762	}
763	SCOPE void
764	rde_param_i_ast_pop_discard (RDE_PARAM p)
765	{
766	    rde_stack_pop (p->mark, 1);
767	}
768	SCOPE void
769	rde_param_i_ast_pop_rewind (RDE_PARAM p)
770	{
771	    long int trim = (long int) rde_stack_top (p->mark);
772	    ENTER ("rde_param_i_ast_pop_rewind");
773	    TRACE (("RDE_PARAM %p",p));
774	    rde_stack_pop  (p->mark, 1);
775	    rde_stack_trim (p->ast, (int) trim);
776	    TRACE (("SV = (%p rc%d '%s')",
777		    p->SV,
778		    p->SV ? p->SV->refCount       : -1,
779		    p->SV ? Tcl_GetString (p->SV) : ""));
780	    RETURNVOID;
781	}
782	SCOPE void
783	rde_param_i_ast_rewind (RDE_PARAM p)
784	{
785	    long int trim = (long int) rde_stack_top (p->mark);
786	    ENTER ("rde_param_i_ast_rewind");
787	    TRACE (("RDE_PARAM %p",p));
788	    rde_stack_trim (p->ast, (int) trim);
789	    TRACE (("SV = (%p rc%d '%s')",
790		    p->SV,
791		    p->SV ? p->SV->refCount       : -1,
792		    p->SV ? Tcl_GetString (p->SV) : ""));
793	    RETURNVOID;
794	}
795	SCOPE void
796	rde_param_i_ast_push (RDE_PARAM p)
797	{
798	    rde_stack_push (p->mark, (void*) rde_stack_size (p->ast));
799	}
800	SCOPE void
801	rde_param_i_ast_value_push (RDE_PARAM p)
802	{
803	    ENTER ("rde_param_i_ast_value_push");
804	    TRACE (("RDE_PARAM %p",p));
805	    ASSERT(p->SV,"Unable to push undefined semantic value");
806	    TRACE (("rde_param_i_ast_value_push %p => (%p)/%d", p, p->SV, ));
807	    TRACE (("SV = (%p rc%d '%s')", p->SV, p->SV->refCount, Tcl_GetString (p->SV)));
808	    rde_stack_push (p->ast, p->SV);
809	    Tcl_IncrRefCount (p->SV);
810	    RETURNVOID;
811	}
812	static void
813	ast_node_free (void* n)
814	{
815	    Tcl_DecrRefCount ((Tcl_Obj*) n);
816	}
817	SCOPE void
818	rde_param_i_error_clear (RDE_PARAM p)
819	{
820	    ER_CLEAR (p);
821	}
822	SCOPE void
823	rde_param_i_error_nonterminal (RDE_PARAM p, int s)
824	{
825	    long int pos;
826	    if (!p->ER) return;
827	    pos = 1 + (long int) rde_stack_top (p->LS);
828	    if (p->ER->loc != pos) return;
829	    error_set (p, s);
830	    p->ER->loc = pos;
831	}
832	SCOPE void
833	rde_param_i_error_pop_merge (RDE_PARAM p)
834	{
835	    ERROR_STATE* top = (ERROR_STATE*) rde_stack_top (p->ES);
836	    
837	    if (top == p->ER) {
838		rde_stack_pop (p->ES, 1);
839		return;
840	    }
841	    
842	    if (!top) {
843		rde_stack_pop (p->ES, 1);
844		return;
845	    }
846	    
847	    if (!p->ER) {
848		rde_stack_drop (p->ES, 1);
849		p->ER = top;
850		
851		return;
852	    }
853	    
854	    if (top->loc < p->ER->loc) {
855		rde_stack_pop (p->ES, 1);
856		return;
857	    }
858	    
859	    if (top->loc > p->ER->loc) {
860		rde_stack_drop (p->ES, 1);
861		error_state_free (p->ER);
862		p->ER = top;
863		
864		return;
865	    }
866	    
867	    rde_stack_move (p->ER->msg, top->msg);
868	    rde_stack_pop  (p->ES, 1);
869	}
870	SCOPE void
871	rde_param_i_error_push (RDE_PARAM p)
872	{
873	    rde_stack_push (p->ES, p->ER);
874	    if (p->ER) { p->ER->refCount ++; }
875	}
876	static void
877	error_set (RDE_PARAM p, int s)
878	{
879	    error_state_free (p->ER);
880	    p->ER = ALLOC (ERROR_STATE);
881	    p->ER->refCount = 1;
882	    p->ER->loc      = p->CL;
883	    p->ER->msg      = rde_stack_new (NULL);
884	    ASSERT_BOUNDS(s,p->numstr);
885	    rde_stack_push (p->ER->msg, (void*) s);
886	}
887	static void
888	error_state_free (void* esx)
889	{
890	    ERROR_STATE* es = esx;
891	    if (!es) return;
892	    es->refCount --;
893	    if (es->refCount > 0) return;
894	    rde_stack_del (es->msg);
895	    ckfree ((char*) es);
896	}
897	SCOPE void
898	rde_param_i_loc_pop_discard (RDE_PARAM p)
899	{
900	    rde_stack_pop (p->LS, 1);
901	}
902	SCOPE void
903	rde_param_i_loc_pop_rewind (RDE_PARAM p)
904	{
905	    p->CL = (long int) rde_stack_top (p->LS);
906	    rde_stack_pop (p->LS, 1);
907	}
908	SCOPE void
909	rde_param_i_loc_push (RDE_PARAM p)
910	{
911	    rde_stack_push (p->LS, (void*) p->CL);
912	}
913	SCOPE void
914	rde_param_i_loc_rewind (RDE_PARAM p)
915	{
916	    p->CL = (long int) rde_stack_top (p->LS);
917	}
918	SCOPE void
919	rde_param_i_input_next (RDE_PARAM p, int m)
920	{
921	    int leni;
922	    char* ch;
923	    ASSERT_BOUNDS(m,p->numstr);
924	    p->CL ++;
925	    if (p->CL < rde_tc_size (p->TC)) {
926		
927		rde_tc_get (p->TC, p->CL, &p->CC, &p->CC_len);
928		ASSERT_BOUNDS (p->CC_len, TCL_UTF_MAX);
929		p->ST = 1;
930		ER_CLEAR (p);
931		return;
932	    }
933	    if (!p->IN || 
934		Tcl_Eof (p->IN) ||
935		(Tcl_ReadChars (p->IN, p->readbuf, 1, 0) <= 0)) {
936		
937		p->ST = 0;
938		error_set (p, m);
939		return;
940	    }
941	    
942	    ch = Tcl_GetStringFromObj (p->readbuf, &leni);
943	    ASSERT_BOUNDS (leni, TCL_UTF_MAX);
944	    p->CC = rde_tc_append (p->TC, ch, leni);
945	    p->CC_len = leni;
946	    p->ST = 1;
947	    ER_CLEAR (p);
948	}
949	SCOPE void
950	rde_param_i_status_fail (RDE_PARAM p)
951	{
952	    p->ST = 0;
953	}
954	SCOPE void
955	rde_param_i_status_ok (RDE_PARAM p)
956	{
957	    p->ST = 1;
958	}
959	SCOPE void
960	rde_param_i_status_negate (RDE_PARAM p)
961	{
962	    p->ST = !p->ST;
963	}
964	SCOPE int 
965	rde_param_i_symbol_restore (RDE_PARAM p, int s)
966	{
967	    NC_STATE*      scs;
968	    Tcl_HashEntry* hPtr;
969	    Tcl_HashTable* tablePtr;
970	    
971	    hPtr = Tcl_FindHashEntry (&p->NC, (char*) p->CL);
972	    if (!hPtr) { return 0; }
973	    tablePtr = (Tcl_HashTable*) Tcl_GetHashValue (hPtr);
974	    hPtr = Tcl_FindHashEntry (tablePtr, (char*) s);
975	    if (!hPtr) { return 0; }
976	    
977	    scs = Tcl_GetHashValue (hPtr);
978	    p->CL = scs->CL;
979	    p->ST = scs->ST;
980	    error_state_free (p->ER);
981	    p->ER = scs->ER;
982	    if (p->ER) { p->ER->refCount ++; }
983	    TRACE (("SV_RESTORE (%p) '%s'",scs->SV, scs->SV ? Tcl_GetString (scs->SV):""));
984	    SV_SET (p, scs->SV);
985	    return 1;
986	}
987	SCOPE void
988	rde_param_i_symbol_save (RDE_PARAM p, int s)
989	{
990	    long int       at = (long int) rde_stack_top (p->LS);
991	    NC_STATE*      scs;
992	    Tcl_HashEntry* hPtr;
993	    Tcl_HashTable* tablePtr;
994	    int            isnew;
995	    ENTER ("rde_param_i_symbol_save");
996	    TRACE (("RDE_PARAM %p",p));
997	    TRACE (("INT       %d",s));
998	    
999	    hPtr = Tcl_CreateHashEntry (&p->NC, (char*) at, &isnew);
1000	    if (isnew) {
1001		tablePtr = ALLOC (Tcl_HashTable);
1002		Tcl_InitHashTable (tablePtr, TCL_ONE_WORD_KEYS);
1003		Tcl_SetHashValue (hPtr, tablePtr);
1004	    } else {
1005		tablePtr = (Tcl_HashTable*) Tcl_GetHashValue (hPtr);
1006	    }
1007	    hPtr = Tcl_CreateHashEntry (tablePtr, (char*) s, &isnew);
1008	    if (isnew) {
1009		
1010		scs = ALLOC (NC_STATE);
1011		scs->CL = p->CL;
1012		scs->ST = p->ST;
1013		TRACE (("SV_CACHE (%p '%s')", p->SV, p->SV ? Tcl_GetString(p->SV) : ""));
1014		scs->SV = p->SV;
1015		if (scs->SV) { Tcl_IncrRefCount (scs->SV); }
1016		scs->ER = p->ER;
1017		if (scs->ER) { scs->ER->refCount ++; }
1018		Tcl_SetHashValue (hPtr, scs);
1019	    } else {
1020		
1021		scs = (NC_STATE*) Tcl_GetHashValue (hPtr);
1022		scs->CL = p->CL;
1023		scs->ST = p->ST;
1024		TRACE (("SV_CACHE/over (%p '%s')", p->SV, p->SV ? Tcl_GetString(p->SV) : "" ));
1025		if (scs->SV) { Tcl_DecrRefCount (scs->SV); }
1026		scs->SV = p->SV;
1027		if (scs->SV) { Tcl_IncrRefCount (scs->SV); }
1028		error_state_free (scs->ER);
1029		scs->ER = p->ER;
1030		if (scs->ER) { scs->ER->refCount ++; }
1031	    }
1032	    TRACE (("SV = (%p rc%d '%s')",
1033		    p->SV,
1034		    p->SV ? p->SV->refCount       : -1,
1035		    p->SV ? Tcl_GetString (p->SV) : ""));
1036	    RETURNVOID;
1037	}
1038	SCOPE void
1039	rde_param_i_test_alnum (RDE_PARAM p)
1040	{
1041	    test_class (p, Tcl_UniCharIsAlnum, tc_alnum);
1042	}
1043	SCOPE void
1044	rde_param_i_test_alpha (RDE_PARAM p)
1045	{
1046	    test_class (p, Tcl_UniCharIsAlpha, tc_alpha);
1047	}
1048	SCOPE void
1049	rde_param_i_test_ascii (RDE_PARAM p)
1050	{
1051	    test_class (p, UniCharIsAscii, tc_ascii);
1052	}
1053	SCOPE void
1054	rde_param_i_test_char (RDE_PARAM p, char* c, int msg)
1055	{
1056	    ASSERT_BOUNDS(msg,p->numstr);
1057	    p->ST = Tcl_UtfNcmp (p->CC, c, 1) == 0;
1058	    if (p->ST) {
1059		ER_CLEAR (p);
1060	    } else {
1061		error_set (p, msg);
1062		p->CL --;
1063	    }
1064	}
1065	SCOPE void
1066	rde_param_i_test_ddigit (RDE_PARAM p)
1067	{
1068	    test_class (p, UniCharIsDecDigit, tc_ddigit);
1069	}
1070	SCOPE void
1071	rde_param_i_test_digit (RDE_PARAM p)
1072	{
1073	    test_class (p, Tcl_UniCharIsDigit, tc_digit);
1074	}
1075	SCOPE void
1076	rde_param_i_test_graph (RDE_PARAM p)
1077	{
1078	    test_class (p, Tcl_UniCharIsGraph, tc_graph);
1079	}
1080	SCOPE void
1081	rde_param_i_test_lower (RDE_PARAM p)
1082	{
1083	    test_class (p, Tcl_UniCharIsLower, tc_lower);
1084	}
1085	SCOPE void
1086	rde_param_i_test_print (RDE_PARAM p)
1087	{
1088	    test_class (p, Tcl_UniCharIsPrint, tc_printable);
1089	}
1090	SCOPE void
1091	rde_param_i_test_punct (RDE_PARAM p)
1092	{
1093	    test_class (p, Tcl_UniCharIsPunct, tc_punct);
1094	}
1095	SCOPE void
1096	rde_param_i_test_range (RDE_PARAM p, char* s, char* e, int msg)
1097	{
1098	    ASSERT_BOUNDS(msg,p->numstr);
1099	    p->ST =
1100		(Tcl_UtfNcmp (s, p->CC, 1) <= 0) &&
1101		(Tcl_UtfNcmp (p->CC, e, 1) <= 0);
1102	    if (p->ST) {
1103		ER_CLEAR (p);
1104	    } else {
1105		error_set (p, msg);
1106		p->CL --;
1107	    }
1108	}
1109	SCOPE void
1110	rde_param_i_test_space (RDE_PARAM p)
1111	{
1112	    test_class (p, Tcl_UniCharIsSpace, tc_space);
1113	}
1114	SCOPE void
1115	rde_param_i_test_upper (RDE_PARAM p)
1116	{
1117	    test_class (p, Tcl_UniCharIsUpper, tc_upper);
1118	}
1119	SCOPE void
1120	rde_param_i_test_wordchar (RDE_PARAM p)
1121	{
1122	    test_class (p, Tcl_UniCharIsWordChar, tc_wordchar);
1123	}
1124	SCOPE void
1125	rde_param_i_test_xdigit (RDE_PARAM p)
1126	{
1127	    test_class (p, UniCharIsHexDigit, tc_xdigit);
1128	}
1129	static void
1130	test_class (RDE_PARAM p, UniCharClass class, test_class_id id)
1131	{
1132	    Tcl_UniChar ch;
1133	    Tcl_UtfToUniChar(p->CC, &ch);
1134	    ASSERT_BOUNDS(id,p->numstr);
1135	    p->ST = !!class (ch);
1136	    
1137	    if (p->ST) {
1138		ER_CLEAR (p);
1139	    } else {
1140		error_set (p, id);
1141		p->CL --;
1142	    }
1143	}
1144	static int
1145	UniCharIsAscii (int character)
1146	{
1147	    return (character >= 0) && (character < 0x80);
1148	}
1149	static int
1150	UniCharIsHexDigit (int character)
1151	{
1152	    return (character >= 0) && (character < 0x80) && isxdigit(character);
1153	}
1154	static int
1155	UniCharIsDecDigit (int character)
1156	{
1157	    return (character >= 0) && (character < 0x80) && isdigit(character);
1158	}
1159	SCOPE void
1160	rde_param_i_value_clear (RDE_PARAM p)
1161	{
1162	    SV_CLEAR (p);
1163	}
1164	SCOPE void
1165	rde_param_i_value_leaf (RDE_PARAM p, int s)
1166	{
1167	    Tcl_Obj* newsv;
1168	    Tcl_Obj* ov [3];
1169	    long int pos = 1 + (long int) rde_stack_top (p->LS);
1170	    ASSERT_BOUNDS(s,p->numstr);
1171	    ov [0] = Tcl_NewStringObj (p->string[s], -1);
1172	    ov [1] = Tcl_NewIntObj (pos);
1173	    ov [2] = Tcl_NewIntObj (p->CL);
1174	    newsv = Tcl_NewListObj (3, ov);
1175	    TRACE (("rde_param_i_value_leaf => '%s'",Tcl_GetString (newsv)));
1176	    SV_SET (p, newsv);
1177	}
1178	SCOPE void
1179	rde_param_i_value_reduce (RDE_PARAM p, int s)
1180	{
1181	    Tcl_Obj*  newsv;
1182	    int       oc, i, j;
1183	    Tcl_Obj** ov;
1184	    long int  ac;
1185	    Tcl_Obj** av;
1186	    long int pos   = 1 + (long int) rde_stack_top (p->LS);
1187	    long int mark  = (long int) rde_stack_top (p->mark);
1188	    long int asize = rde_stack_size (p->ast);
1189	    long int new   = asize - mark;
1190	    ASSERT (new >= 0, "Bad number of elements to reduce");
1191	    ov = NALLOC (3+new, Tcl_Obj*);
1192	    ASSERT_BOUNDS(s,p->numstr);
1193	    ov [0] = Tcl_NewStringObj (p->string[s], -1);
1194	    ov [1] = Tcl_NewIntObj (pos);
1195	    ov [2] = Tcl_NewIntObj (p->CL);
1196	    rde_stack_get (p->ast, &ac, (void***) &av);
1197	    for (i = 3, j = mark; j < asize; i++, j++) {
1198		ASSERT_BOUNDS (i, 3+new);
1199		ASSERT_BOUNDS (j, ac);
1200		ov [i] = av [j];
1201	    }
1202	    ASSERT (i == 3+new, "Reduction result incomplete");
1203	    newsv = Tcl_NewListObj (3+new, ov);
1204	    TRACE (("rde_param_i_value_reduce => '%s'",Tcl_GetString (newsv)));
1205	    SV_SET (p, newsv);
1206	    ckfree ((char*) ov);
1207	}
1208	static int
1209	er_int_compare (const void* a, const void* b)
1210	{
1211	    long int ai = *((long int*) a);
1212	    long int bi = *((long int*) b);
1213	    if (ai < bi) { return -1; }
1214	    if (ai > bi) { return  1; }
1215	    return 0;
1216	}
1217	SCOPE int
1218	rde_param_i_symbol_start (RDE_PARAM p, int s)
1219	{
1220	    if (rde_param_i_symbol_restore (p, s)) {
1221		if (p->ST) {
1222		    rde_stack_push (p->ast, p->SV);
1223		    Tcl_IncrRefCount (p->SV);
1224		}
1225		return 1;
1226	    }
1227	    rde_stack_push (p->LS, (void*) p->CL);
1228	    return 0;
1229	}
1230	SCOPE int
1231	rde_param_i_symbol_start_d (RDE_PARAM p, int s)
1232	{
1233	    if (rde_param_i_symbol_restore (p, s)) {
1234		if (p->ST) {
1235		    rde_stack_push (p->ast, p->SV);
1236		    Tcl_IncrRefCount (p->SV);
1237		}
1238		return 1;
1239	    }
1240	    rde_stack_push (p->LS,   (void*) p->CL);
1241	    rde_stack_push (p->mark, (void*) rde_stack_size (p->ast));
1242	    return 0;
1243	}
1244	SCOPE int
1245	rde_param_i_symbol_void_start (RDE_PARAM p, int s)
1246	{
1247	    if (rde_param_i_symbol_restore (p, s)) return 1;
1248	    rde_stack_push (p->LS, (void*) p->CL);
1249	    return 0;
1250	}
1251	SCOPE int
1252	rde_param_i_symbol_void_start_d (RDE_PARAM p, int s)
1253	{
1254	    if (rde_param_i_symbol_restore (p, s)) return 1;
1255	    rde_stack_push (p->LS,   (void*) p->CL);
1256	    rde_stack_push (p->mark, (void*) rde_stack_size (p->ast));
1257	    return 0;
1258	}
1259	SCOPE void
1260	rde_param_i_symbol_done_d_reduce (RDE_PARAM p, int s, int m)
1261	{
1262	    if (p->ST) {
1263		rde_param_i_value_reduce (p, s);
1264	    } else {
1265		SV_CLEAR (p);
1266	    }
1267	    rde_param_i_symbol_save       (p, s);
1268	    rde_param_i_error_nonterminal (p, m);
1269	    rde_param_i_ast_pop_rewind    (p);
1270	    rde_stack_pop (p->LS, 1);
1271	    if (p->ST) {
1272		rde_stack_push (p->ast, p->SV);
1273		Tcl_IncrRefCount (p->SV);
1274	    }
1275	}
1276	SCOPE void
1277	rde_param_i_symbol_done_leaf (RDE_PARAM p, int s, int m)
1278	{
1279	    if (p->ST) {
1280		rde_param_i_value_leaf (p, s);
1281	    } else {
1282		SV_CLEAR (p);
1283	    }
1284	    rde_param_i_symbol_save       (p, s);
1285	    rde_param_i_error_nonterminal (p, m);
1286	    rde_stack_pop (p->LS, 1);
1287	    if (p->ST) {
1288		rde_stack_push (p->ast, p->SV);
1289		Tcl_IncrRefCount (p->SV);
1290	    }
1291	}
1292	SCOPE void
1293	rde_param_i_symbol_done_d_leaf (RDE_PARAM p, int s, int m)
1294	{
1295	    if (p->ST) {
1296		rde_param_i_value_leaf (p, s);
1297	    } else {
1298		SV_CLEAR (p);
1299	    }
1300	    rde_param_i_symbol_save       (p, s);
1301	    rde_param_i_error_nonterminal (p, m);
1302	    rde_param_i_ast_pop_rewind    (p);
1303	    rde_stack_pop (p->LS, 1);
1304	    if (p->ST) {
1305		rde_stack_push (p->ast, p->SV);
1306		Tcl_IncrRefCount (p->SV);
1307	    }
1308	}
1309	SCOPE void
1310	rde_param_i_symbol_done_void (RDE_PARAM p, int s, int m)
1311	{
1312	    SV_CLEAR (p);
1313	    rde_param_i_symbol_save       (p, s);
1314	    rde_param_i_error_nonterminal (p, m);
1315	    rde_stack_pop (p->LS, 1);
1316	}
1317	SCOPE void
1318	rde_param_i_symbol_done_d_void (RDE_PARAM p, int s, int m)
1319	{
1320	    SV_CLEAR (p);
1321	    rde_param_i_symbol_save       (p, s);
1322	    rde_param_i_error_nonterminal (p, m);
1323	    rde_param_i_ast_pop_rewind    (p);
1324	    rde_stack_pop (p->LS, 1);
1325	}
1326	SCOPE void
1327	rde_param_i_next_char (RDE_PARAM p, char* c, int m)
1328	{
1329	    rde_param_i_input_next (p, m);
1330	    if (!p->ST) return;
1331	    rde_param_i_test_char (p, c, m);
1332	}
1333	SCOPE void
1334	rde_param_i_next_range (RDE_PARAM p, char* s, char* e, int m)
1335	{
1336	    rde_param_i_input_next (p, m);
1337	    if (!p->ST) return;
1338	    rde_param_i_test_range (p, s, e, m);
1339	}
1340	SCOPE void
1341	rde_param_i_next_alnum (RDE_PARAM p, int m)
1342	{
1343	    rde_param_i_input_next (p, m);
1344	    if (!p->ST) return;
1345	    rde_param_i_test_alnum (p);
1346	}
1347	SCOPE void
1348	rde_param_i_next_alpha (RDE_PARAM p, int m)
1349	{
1350	    rde_param_i_input_next (p, m);
1351	    if (!p->ST) return;
1352	    rde_param_i_test_alpha (p);
1353	}
1354	SCOPE void
1355	rde_param_i_next_ascii (RDE_PARAM p, int m)
1356	{
1357	    rde_param_i_input_next (p, m);
1358	    if (!p->ST) return;
1359	    rde_param_i_test_ascii (p);
1360	}
1361	SCOPE void
1362	rde_param_i_next_ddigit (RDE_PARAM p, int m)
1363	{
1364	    rde_param_i_input_next (p, m);
1365	    if (!p->ST) return;
1366	    rde_param_i_test_ddigit (p);
1367	}
1368	SCOPE void
1369	rde_param_i_next_digit (RDE_PARAM p, int m)
1370	{
1371	    rde_param_i_input_next (p, m);
1372	    if (!p->ST) return;
1373	    rde_param_i_test_digit (p);
1374	}
1375	SCOPE void
1376	rde_param_i_next_graph (RDE_PARAM p, int m)
1377	{
1378	    rde_param_i_input_next (p, m);
1379	    if (!p->ST) return;
1380	    rde_param_i_test_graph (p);
1381	}
1382	SCOPE void
1383	rde_param_i_next_lower (RDE_PARAM p, int m)
1384	{
1385	    rde_param_i_input_next (p, m);
1386	    if (!p->ST) return;
1387	    rde_param_i_test_lower (p);
1388	}
1389	SCOPE void
1390	rde_param_i_next_print (RDE_PARAM p, int m)
1391	{
1392	    rde_param_i_input_next (p, m);
1393	    if (!p->ST) return;
1394	    rde_param_i_test_print (p);
1395	}
1396	SCOPE void
1397	rde_param_i_next_punct (RDE_PARAM p, int m)
1398	{
1399	    rde_param_i_input_next (p, m);
1400	    if (!p->ST) return;
1401	    rde_param_i_test_punct (p);
1402	}
1403	SCOPE void
1404	rde_param_i_next_space (RDE_PARAM p, int m)
1405	{
1406	    rde_param_i_input_next (p, m);
1407	    if (!p->ST) return;
1408	    rde_param_i_test_space (p);
1409	}
1410	SCOPE void
1411	rde_param_i_next_upper (RDE_PARAM p, int m)
1412	{
1413	    rde_param_i_input_next (p, m);
1414	    if (!p->ST) return;
1415	    rde_param_i_test_upper (p);
1416	}
1417	SCOPE void
1418	rde_param_i_next_wordchar (RDE_PARAM p, int m)
1419	{
1420	    rde_param_i_input_next (p, m);
1421	    if (!p->ST) return;
1422	    rde_param_i_test_wordchar (p);
1423	}
1424	SCOPE void
1425	rde_param_i_next_xdigit (RDE_PARAM p, int m)
1426	{
1427	    rde_param_i_input_next (p, m);
1428	    if (!p->ST) return;
1429	    rde_param_i_test_xdigit (p);
1430	}
1431	SCOPE void
1432	rde_param_i_notahead_start_d (RDE_PARAM p)
1433	{
1434	    rde_stack_push (p->LS, (void*) p->CL);
1435	    rde_stack_push (p->mark, (void*) rde_stack_size (p->ast));
1436	}
1437	SCOPE void
1438	rde_param_i_notahead_exit_d (RDE_PARAM p)
1439	{
1440	    if (p->ST) {
1441		rde_param_i_ast_pop_rewind (p); 
1442	    } else {
1443		rde_stack_pop (p->mark, 1);
1444	    }
1445	    p->CL = (long int) rde_stack_top (p->LS);
1446	    rde_stack_pop (p->LS, 1);
1447	    p->ST = !p->ST;
1448	}
1449	SCOPE void
1450	rde_param_i_notahead_exit (RDE_PARAM p)
1451	{
1452	    p->CL = (long int) rde_stack_top (p->LS);
1453	    rde_stack_pop (p->LS, 1);
1454	    p->ST = !p->ST;
1455	}
1456	SCOPE void
1457	rde_param_i_state_push_2 (RDE_PARAM p)
1458	{
1459	    
1460	    rde_stack_push (p->LS, (void*) p->CL);
1461	    rde_stack_push (p->ES, p->ER);
1462	    if (p->ER) { p->ER->refCount ++; }
1463	}
1464	SCOPE void
1465	rde_param_i_state_push_void (RDE_PARAM p)
1466	{
1467	    rde_stack_push (p->LS, (void*) p->CL);
1468	    ER_CLEAR (p);
1469	    rde_stack_push (p->ES, p->ER);
1470	    
1471	}
1472	SCOPE void
1473	rde_param_i_state_push_value (RDE_PARAM p)
1474	{
1475	    rde_stack_push (p->mark, (void*) rde_stack_size (p->ast));
1476	    rde_stack_push (p->LS, (void*) p->CL);
1477	    ER_CLEAR (p);
1478	    rde_stack_push (p->ES, p->ER);
1479	    
1480	}
1481	SCOPE void
1482	rde_param_i_state_merge_ok (RDE_PARAM p)
1483	{
1484	    rde_param_i_error_pop_merge (p);
1485	    if (!p->ST) {
1486		p->ST = 1;
1487		p->CL = (long int) rde_stack_top (p->LS);
1488	    }
1489	    rde_stack_pop (p->LS, 1);
1490	}
1491	SCOPE void
1492	rde_param_i_state_merge_void (RDE_PARAM p)
1493	{
1494	    rde_param_i_error_pop_merge (p);
1495	    if (!p->ST) {
1496		p->CL = (long int) rde_stack_top (p->LS);
1497	    }
1498	    rde_stack_pop (p->LS, 1);
1499	}
1500	SCOPE void
1501	rde_param_i_state_merge_value (RDE_PARAM p)
1502	{
1503	    rde_param_i_error_pop_merge (p);
1504	    if (!p->ST) {
1505		long int trim = (long int) rde_stack_top (p->mark);
1506		rde_stack_trim (p->ast, (int) trim);
1507		p->CL = (long int) rde_stack_top (p->LS);
1508	    }
1509	    rde_stack_pop (p->mark, 1);
1510	    rde_stack_pop (p->LS, 1);
1511	}
1512	SCOPE int
1513	rde_param_i_kleene_close (RDE_PARAM p)
1514	{
1515	    int stop = !p->ST;
1516	    rde_param_i_error_pop_merge (p);
1517	    if (stop) {
1518		p->ST = 1;
1519		p->CL = (long int) rde_stack_top (p->LS);
1520	    }
1521	    rde_stack_pop (p->LS, 1);
1522	    return stop;
1523	}
1524	SCOPE int
1525	rde_param_i_kleene_abort (RDE_PARAM p)
1526	{
1527	    int stop = !p->ST;
1528	    if (stop) {
1529		p->CL = (long int) rde_stack_top (p->LS);
1530	    }
1531	    rde_stack_pop (p->LS, 1);
1532	    return stop;
1533	}
1534	SCOPE int
1535	rde_param_i_seq_void2void (RDE_PARAM p)
1536	{
1537	    rde_param_i_error_pop_merge (p);
1538	    if (p->ST) {
1539		rde_stack_push (p->ES, p->ER);
1540		if (p->ER) { p->ER->refCount ++; }
1541		return 0;
1542	    } else {
1543		p->CL = (long int) rde_stack_top (p->LS);
1544		rde_stack_pop (p->LS, 1);
1545		return 1;
1546	    }
1547	}
1548	SCOPE int
1549	rde_param_i_seq_void2value (RDE_PARAM p)
1550	{
1551	    rde_param_i_error_pop_merge (p);
1552	    if (p->ST) {
1553		rde_stack_push (p->mark, (void*) rde_stack_size (p->ast));
1554		rde_stack_push (p->ES, p->ER);
1555		if (p->ER) { p->ER->refCount ++; }
1556		return 0;
1557	    } else {
1558		p->CL = (long int) rde_stack_top (p->LS);
1559		rde_stack_pop (p->LS, 1);
1560		return 1;
1561	    }
1562	}
1563	SCOPE int
1564	rde_param_i_seq_value2value (RDE_PARAM p)
1565	{
1566	    rde_param_i_error_pop_merge (p);
1567	    if (p->ST) {
1568		rde_stack_push (p->ES, p->ER);
1569		if (p->ER) { p->ER->refCount ++; }
1570		return 0;
1571	    } else {
1572		long int trim = (long int) rde_stack_top (p->mark);
1573		rde_stack_pop  (p->mark, 1);
1574		rde_stack_trim (p->ast, (int) trim);
1575		p->CL = (long int) rde_stack_top (p->LS);
1576		rde_stack_pop (p->LS, 1);
1577		return 1;
1578	    }
1579	}
1580	SCOPE int
1581	rde_param_i_bra_void2void (RDE_PARAM p)
1582	{
1583	    rde_param_i_error_pop_merge (p);
1584	    if (p->ST) {
1585		rde_stack_pop (p->LS, 1);
1586	    } else {
1587		p->CL = (long int) rde_stack_top (p->LS);
1588		rde_stack_push (p->ES, p->ER);
1589		if (p->ER) { p->ER->refCount ++; }
1590	    }
1591	    return p->ST;
1592	}
1593	SCOPE int
1594	rde_param_i_bra_void2value (RDE_PARAM p)
1595	{
1596	    rde_param_i_error_pop_merge (p);
1597	    if (p->ST) {
1598		rde_stack_pop (p->LS, 1);
1599	    } else {
1600		rde_stack_push (p->mark, (void*) rde_stack_size (p->ast));
1601		p->CL = (long int) rde_stack_top (p->LS);
1602		rde_stack_push (p->ES, p->ER);
1603		if (p->ER) { p->ER->refCount ++; }
1604	    }
1605	    return p->ST;
1606	}
1607	SCOPE int
1608	rde_param_i_bra_value2void (RDE_PARAM p)
1609	{
1610	    rde_param_i_error_pop_merge (p);
1611	    if (p->ST) {
1612		rde_stack_pop (p->mark, 1);
1613		rde_stack_pop (p->LS, 1);
1614	    } else {
1615		long int trim = (long int) rde_stack_top (p->mark);
1616		rde_stack_pop  (p->mark, 1);
1617		rde_stack_trim (p->ast, (int) trim);
1618		p->CL = (long int) rde_stack_top (p->LS);
1619		rde_stack_push (p->ES, p->ER);
1620		if (p->ER) { p->ER->refCount ++; }
1621	    }
1622	    return p->ST;
1623	}
1624	SCOPE int
1625	rde_param_i_bra_value2value (RDE_PARAM p)
1626	{
1627	    rde_param_i_error_pop_merge (p);
1628	    if (p->ST) {
1629		rde_stack_pop (p->mark, 1);
1630		rde_stack_pop (p->LS, 1);
1631	    } else {
1632		long int trim = (long int) rde_stack_top (p->mark);
1633		rde_stack_trim (p->ast, (int) trim);
1634		p->CL = (long int) rde_stack_top (p->LS);
1635		rde_stack_push (p->ES, p->ER);
1636		if (p->ER) { p->ER->refCount ++; }
1637	    }
1638	    return p->ST;
1639	}
1640	SCOPE void
1641	rde_param_i_next_str (RDE_PARAM p, char* str, int m)
1642	{
1643	    int at = p->CL;
1644	    while (*str) {
1645		rde_param_i_input_next (p, m);
1646		if (!p->ST) {
1647		    p->CL = at;
1648		    return;
1649		}
1650		rde_param_i_test_char (p, str, m);
1651		if (!p->ST) {
1652		    p->CL = at;
1653		    return;
1654		}
1655		str = Tcl_UtfNext (str);
1656	    }
1657	}
1658	SCOPE void
1659	rde_param_i_next_class (RDE_PARAM p, char* class, int m)
1660	{
1661	    rde_param_i_input_next (p, m);
1662	    if (!p->ST) return;
1663	    while (*class) {
1664		p->ST = Tcl_UtfNcmp (p->CC, class, 1) == 0;
1665		if (p->ST) {
1666		    ER_CLEAR (p);
1667		    return;
1668		}
1669		class = Tcl_UtfNext (class);
1670	    }
1671	    error_set (p, m);
1672	    p->CL --;
1673	}
1674	
1675
1676    }
1677
1678    # # ## ### ###### ######## #############
1679    ## BEGIN of GENERATED CODE. DO NOT EDIT.
1680
1681    critcl::ccode {
1682	/* -*- c -*- */
1683
1684        /*
1685         * Declaring the parse functions
1686         */
1687        
1688        static void sym_AddOp (RDE_PARAM p);
1689        static void sym_Digit (RDE_PARAM p);
1690        static void sequence_10 (RDE_PARAM p);
1691        static void sequence_15 (RDE_PARAM p);
1692        static void kleene_17 (RDE_PARAM p);
1693        static void sequence_19 (RDE_PARAM p);
1694        static void choice_21 (RDE_PARAM p);
1695        static void sym_Expression (RDE_PARAM p);
1696        static void sequence_27 (RDE_PARAM p);
1697        static void kleene_29 (RDE_PARAM p);
1698        static void sequence_31 (RDE_PARAM p);
1699        static void sym_Factor (RDE_PARAM p);
1700        static void sym_Function (RDE_PARAM p);
1701        static void sym_MulOp (RDE_PARAM p);
1702        static void optional_39 (RDE_PARAM p);
1703        static void poskleene_42 (RDE_PARAM p);
1704        static void sequence_44 (RDE_PARAM p);
1705        static void sym_Number (RDE_PARAM p);
1706        static void sym_Sign (RDE_PARAM p);
1707        static void sequence_52 (RDE_PARAM p);
1708        static void sym_Sinus (RDE_PARAM p);
1709        static void sym_Term (RDE_PARAM p);
1710        
1711        /*
1712         * Precomputed table of strings (symbols, error messages, etc.).
1713         */
1714        
1715        static char const* p_string [26] = {
1716            /*        0 = */   "cl '-+'",
1717            /*        1 = */   "n AddOp",
1718            /*        2 = */   "AddOp",
1719            /*        3 = */   "cl '0123456789'",
1720            /*        4 = */   "n Digit",
1721            /*        5 = */   "Digit",
1722            /*        6 = */   "t \50",
1723            /*        7 = */   "t \51",
1724            /*        8 = */   "n Expression",
1725            /*        9 = */   "Expression",
1726            /*       10 = */   "n Factor",
1727            /*       11 = */   "Factor",
1728            /*       12 = */   "n Function",
1729            /*       13 = */   "Function",
1730            /*       14 = */   "cl '*/'",
1731            /*       15 = */   "n MulOp",
1732            /*       16 = */   "MulOp",
1733            /*       17 = */   "n Number",
1734            /*       18 = */   "Number",
1735            /*       19 = */   "n Sign",
1736            /*       20 = */   "Sign",
1737            /*       21 = */   "str 'sin\50'",
1738            /*       22 = */   "n Sinus",
1739            /*       23 = */   "Sinus",
1740            /*       24 = */   "n Term",
1741            /*       25 = */   "Term"
1742        };
1743        
1744        /*
1745         * Grammar Start Expression
1746         */
1747        
1748        static void MAIN (RDE_PARAM p) {
1749            sym_Expression (p);
1750            return;
1751        }
1752        
1753        /*
1754         * value Symbol 'AddOp'
1755         */
1756        
1757        static void sym_AddOp (RDE_PARAM p) {
1758           /*
1759            * [-+]
1760            */
1761        
1762            if (rde_param_i_symbol_start (p, 2)) return ;
1763            rde_param_i_next_class (p, "-+", 0);
1764            rde_param_i_symbol_done_leaf (p, 2, 1);
1765            return;
1766        }
1767        
1768        /*
1769         * value Symbol 'Digit'
1770         */
1771        
1772        static void sym_Digit (RDE_PARAM p) {
1773           /*
1774            * [0123456789]
1775            */
1776        
1777            if (rde_param_i_symbol_start (p, 5)) return ;
1778            rde_param_i_next_class (p, "0123456789", 3);
1779            rde_param_i_symbol_done_leaf (p, 5, 4);
1780            return;
1781        }
1782        
1783        /*
1784         * value Symbol 'Expression'
1785         */
1786        
1787        static void sym_Expression (RDE_PARAM p) {
1788           /*
1789            * /
1790            *     (Function)
1791            *     x
1792            *         '\('
1793            *         (Expression)
1794            *         '\)'
1795            *     x
1796            *         (Factor)
1797            *         *
1798            *             x
1799            *                 (MulOp)
1800            *                 (Factor)
1801            */
1802        
1803            if (rde_param_i_symbol_start_d (p, 9)) return ;
1804            choice_21 (p);
1805            rde_param_i_symbol_done_d_reduce (p, 9, 8);
1806            return;
1807        }
1808        
1809        static void choice_21 (RDE_PARAM p) {
1810           /*
1811            * /
1812            *     (Function)
1813            *     x
1814            *         '\('
1815            *         (Expression)
1816            *         '\)'
1817            *     x
1818            *         (Factor)
1819            *         *
1820            *             x
1821            *                 (MulOp)
1822            *                 (Factor)
1823            */
1824        
1825            rde_param_i_state_push_value (p);
1826            sym_Function (p);
1827            if (rde_param_i_bra_value2value(p)) return;
1828            sequence_10 (p);
1829            if (rde_param_i_bra_value2value(p)) return;
1830            sequence_19 (p);
1831            rde_param_i_state_merge_value (p);
1832            return;
1833        }
1834        
1835        static void sequence_10 (RDE_PARAM p) {
1836           /*
1837            * x
1838            *     '\('
1839            *     (Expression)
1840            *     '\)'
1841            */
1842        
1843            rde_param_i_state_push_void (p);
1844            rde_param_i_next_char (p, "\50", 6);
1845            if (rde_param_i_seq_void2value(p)) return;
1846            sym_Expression (p);
1847            if (rde_param_i_seq_value2value(p)) return;
1848            rde_param_i_next_char (p, "\51", 7);
1849            rde_param_i_state_merge_value (p);
1850            return;
1851        }
1852        
1853        static void sequence_19 (RDE_PARAM p) {
1854           /*
1855            * x
1856            *     (Factor)
1857            *     *
1858            *         x
1859            *             (MulOp)
1860            *             (Factor)
1861            */
1862        
1863            rde_param_i_state_push_value (p);
1864            sym_Factor (p);
1865            if (rde_param_i_seq_value2value(p)) return;
1866            kleene_17 (p);
1867            rde_param_i_state_merge_value (p);
1868            return;
1869        }
1870        
1871        static void kleene_17 (RDE_PARAM p) {
1872           /*
1873            * *
1874            *     x
1875            *         (MulOp)
1876            *         (Factor)
1877            */
1878        
1879            while (1) {
1880                rde_param_i_state_push_2 (p);
1881                sequence_15 (p);
1882                if (rde_param_i_kleene_close(p)) return;
1883            }
1884            return;
1885        }
1886        
1887        static void sequence_15 (RDE_PARAM p) {
1888           /*
1889            * x
1890            *     (MulOp)
1891            *     (Factor)
1892            */
1893        
1894            rde_param_i_state_push_value (p);
1895            sym_MulOp (p);
1896            if (rde_param_i_seq_value2value(p)) return;
1897            sym_Factor (p);
1898            rde_param_i_state_merge_value (p);
1899            return;
1900        }
1901        
1902        /*
1903         * value Symbol 'Factor'
1904         */
1905        
1906        static void sym_Factor (RDE_PARAM p) {
1907           /*
1908            * x
1909            *     (Term)
1910            *     *
1911            *         x
1912            *             (AddOp)
1913            *             (Term)
1914            */
1915        
1916            if (rde_param_i_symbol_start_d (p, 11)) return ;
1917            sequence_31 (p);
1918            rde_param_i_symbol_done_d_reduce (p, 11, 10);
1919            return;
1920        }
1921        
1922        static void sequence_31 (RDE_PARAM p) {
1923           /*
1924            * x
1925            *     (Term)
1926            *     *
1927            *         x
1928            *             (AddOp)
1929            *             (Term)
1930            */
1931        
1932            rde_param_i_state_push_value (p);
1933            sym_Term (p);
1934            if (rde_param_i_seq_value2value(p)) return;
1935            kleene_29 (p);
1936            rde_param_i_state_merge_value (p);
1937            return;
1938        }
1939        
1940        static void kleene_29 (RDE_PARAM p) {
1941           /*
1942            * *
1943            *     x
1944            *         (AddOp)
1945            *         (Term)
1946            */
1947        
1948            while (1) {
1949                rde_param_i_state_push_2 (p);
1950                sequence_27 (p);
1951                if (rde_param_i_kleene_close(p)) return;
1952            }
1953            return;
1954        }
1955        
1956        static void sequence_27 (RDE_PARAM p) {
1957           /*
1958            * x
1959            *     (AddOp)
1960            *     (Term)
1961            */
1962        
1963            rde_param_i_state_push_value (p);
1964            sym_AddOp (p);
1965            if (rde_param_i_seq_value2value(p)) return;
1966            sym_Term (p);
1967            rde_param_i_state_merge_value (p);
1968            return;
1969        }
1970        
1971        /*
1972         * value Symbol 'Function'
1973         */
1974        
1975        static void sym_Function (RDE_PARAM p) {
1976           /*
1977            * (Sinus)
1978            */
1979        
1980            if (rde_param_i_symbol_start_d (p, 13)) return ;
1981            sym_Sinus (p);
1982            rde_param_i_symbol_done_d_reduce (p, 13, 12);
1983            return;
1984        }
1985        
1986        /*
1987         * value Symbol 'MulOp'
1988         */
1989        
1990        static void sym_MulOp (RDE_PARAM p) {
1991           /*
1992            * [*/]
1993            */
1994        
1995            if (rde_param_i_symbol_start (p, 16)) return ;
1996            rde_param_i_next_class (p, "*/", 14);
1997            rde_param_i_symbol_done_leaf (p, 16, 15);
1998            return;
1999        }
2000        
2001        /*
2002         * value Symbol 'Number'
2003         */
2004        
2005        static void sym_Number (RDE_PARAM p) {
2006           /*
2007            * x
2008            *     ?
2009            *         (Sign)
2010            *     +
2011            *         (Digit)
2012            */
2013        
2014            if (rde_param_i_symbol_start_d (p, 18)) return ;
2015            sequence_44 (p);
2016            rde_param_i_symbol_done_d_reduce (p, 18, 17);
2017            return;
2018        }
2019        
2020        static void sequence_44 (RDE_PARAM p) {
2021           /*
2022            * x
2023            *     ?
2024            *         (Sign)
2025            *     +
2026            *         (Digit)
2027            */
2028        
2029            rde_param_i_state_push_value (p);
2030            optional_39 (p);
2031            if (rde_param_i_seq_value2value(p)) return;
2032            poskleene_42 (p);
2033            rde_param_i_state_merge_value (p);
2034            return;
2035        }
2036        
2037        static void optional_39 (RDE_PARAM p) {
2038           /*
2039            * ?
2040            *     (Sign)
2041            */
2042        
2043            rde_param_i_state_push_2 (p);
2044            sym_Sign (p);
2045            rde_param_i_state_merge_ok (p);
2046            return;
2047        }
2048        
2049        static void poskleene_42 (RDE_PARAM p) {
2050           /*
2051            * +
2052            *     (Digit)
2053            */
2054        
2055            rde_param_i_loc_push (p);
2056            sym_Digit (p);
2057            if (rde_param_i_kleene_abort(p)) return;
2058            while (1) {
2059                rde_param_i_state_push_2 (p);
2060                sym_Digit (p);
2061                if (rde_param_i_kleene_close(p)) return;
2062            }
2063            return;
2064        }
2065        
2066        /*
2067         * value Symbol 'Sign'
2068         */
2069        
2070        static void sym_Sign (RDE_PARAM p) {
2071           /*
2072            * [-+]
2073            */
2074        
2075            if (rde_param_i_symbol_start (p, 20)) return ;
2076            rde_param_i_next_class (p, "-+", 0);
2077            rde_param_i_symbol_done_leaf (p, 20, 19);
2078            return;
2079        }
2080        
2081        /*
2082         * value Symbol 'Sinus'
2083         */
2084        
2085        static void sym_Sinus (RDE_PARAM p) {
2086           /*
2087            * x
2088            *     "sin\("
2089            *     (Expression)
2090            *     '\)'
2091            */
2092        
2093            if (rde_param_i_symbol_start_d (p, 23)) return ;
2094            sequence_52 (p);
2095            rde_param_i_symbol_done_d_reduce (p, 23, 22);
2096            return;
2097        }
2098        
2099        static void sequence_52 (RDE_PARAM p) {
2100           /*
2101            * x
2102            *     "sin\("
2103            *     (Expression)
2104            *     '\)'
2105            */
2106        
2107            rde_param_i_state_push_void (p);
2108            rde_param_i_next_str (p, "sin\50", 21);
2109            if (rde_param_i_seq_void2value(p)) return;
2110            sym_Expression (p);
2111            if (rde_param_i_seq_value2value(p)) return;
2112            rde_param_i_next_char (p, "\51", 7);
2113            rde_param_i_state_merge_value (p);
2114            return;
2115        }
2116        
2117        /*
2118         * value Symbol 'Term'
2119         */
2120        
2121        static void sym_Term (RDE_PARAM p) {
2122           /*
2123            * (Number)
2124            */
2125        
2126            if (rde_param_i_symbol_start_d (p, 25)) return ;
2127            sym_Number (p);
2128            rde_param_i_symbol_done_d_reduce (p, 25, 24);
2129            return;
2130        }
2131        
2132    }
2133
2134    ## END of GENERATED CODE. DO NOT EDIT.
2135    # # ## ### ###### ######## #############
2136
2137    # # ## ### ###### ######## #############
2138    ## Global PARSER management, per interp
2139
2140    critcl::ccode {
2141	/* -*- c -*- */
2142
2143	typedef struct PARSERg {
2144	    long int counter;
2145	    char     buf [50];
2146	} PARSERg;
2147
2148	static void
2149	PARSERgRelease (ClientData cd, Tcl_Interp* interp)
2150	{
2151	    ckfree((char*) cd);
2152	}
2153
2154	static const char*
2155	PARSERnewName (Tcl_Interp* interp)
2156	{
2157#define KEY "tcllib/parser/PACKAGE/critcl"
2158
2159	    Tcl_InterpDeleteProc* proc = PARSERgRelease;
2160	    PARSERg*                  parserg;
2161
2162	    parserg = Tcl_GetAssocData (interp, KEY, &proc);
2163	    if (parserg  == NULL) {
2164		parserg = (PARSERg*) ckalloc (sizeof (PARSERg));
2165		parserg->counter = 0;
2166
2167		Tcl_SetAssocData (interp, KEY, proc,
2168				  (ClientData) parserg);
2169	    }
2170
2171	    parserg->counter ++;
2172	    sprintf (parserg->buf, "PARSER%d", parserg->counter);
2173	    return parserg->buf;
2174#undef  KEY
2175	}
2176
2177	static void
2178	PARSERdeleteCmd (ClientData clientData)
2179	{
2180	    /*
2181	     * Release the whole PARSER
2182	     * (Low-level engine only actually).
2183	     */
2184	    rde_param_del ((RDE_PARAM) clientData);
2185	}
2186    }
2187
2188    # # ## ### ##### ######## #############
2189    ## Functions implementing the object methods, and helper.
2190
2191    critcl::ccode {
2192	static int  COMPLETE (RDE_PARAM p, Tcl_Interp* interp);
2193
2194	static int parser_PARSE  (RDE_PARAM p, Tcl_Interp* interp, int objc, Tcl_Obj* CONST* objv)
2195	{
2196	    int mode;
2197	    Tcl_Channel chan;
2198
2199	    if (objc != 3) {
2200		Tcl_WrongNumArgs (interp, 2, objv, "chan");
2201		return TCL_ERROR;
2202	    }
2203
2204	    chan = Tcl_GetChannel(interp,
2205				  Tcl_GetString (objv[2]),
2206				  &mode);
2207
2208	    if (!chan) {
2209		return TCL_ERROR;
2210	    }
2211
2212	    rde_param_reset (p, chan);
2213	    MAIN (p) ; /* Entrypoint for the generated code. */
2214	    return COMPLETE (p, interp);
2215	}
2216
2217	static int parser_PARSET (RDE_PARAM p, Tcl_Interp* interp, int objc, Tcl_Obj* CONST* objv)
2218	{
2219	    char* buf;
2220	    int   len;
2221
2222	    if (objc != 3) {
2223		Tcl_WrongNumArgs (interp, 2, objv, "text");
2224		return TCL_ERROR;
2225	    }
2226
2227	    buf = Tcl_GetStringFromObj (objv[2], &len);
2228
2229	    rde_param_reset (p, NULL);
2230	    rde_param_data  (p, buf, len);
2231	    MAIN (p) ; /* Entrypoint for the generated code. */
2232	    return COMPLETE (p, interp);
2233	}
2234
2235	static int COMPLETE (RDE_PARAM p, Tcl_Interp* interp)
2236	{
2237	    if (rde_param_query_st (p)) {
2238		long int  ac;
2239		Tcl_Obj** av;
2240
2241		rde_param_query_ast (p, &ac, &av);
2242
2243		if (ac > 1) {
2244		    long int  lsc;
2245		    long int* lsv;
2246		    Tcl_Obj** lv = NALLOC (3+ac, Tcl_Obj*);
2247
2248		    rde_param_query_ls (p, &lsc, &lsv);
2249
2250		    memcpy(lv + 3, av, ac * sizeof (Tcl_Obj*));
2251		    lv [0] = Tcl_NewObj ();
2252		    lv [1] = Tcl_NewIntObj (1 + lsv [lsc-1]);
2253		    lv [2] = Tcl_NewIntObj (rde_param_query_cl (p));
2254
2255		    Tcl_SetObjResult (interp, Tcl_NewListObj (3, lv));
2256		    ckfree ((char*) lv);
2257		} else {
2258		    Tcl_SetObjResult (interp, av [0]);
2259		}
2260
2261		return TCL_OK;
2262	    } else {
2263		Tcl_Obj* xv [1];
2264		const ERROR_STATE* er = rde_param_query_er (p);
2265		Tcl_Obj* res = rde_param_query_er_tcl (p, er);
2266
2267		xv [0] = Tcl_NewStringObj ("pt::rde",-1);
2268		Tcl_ListObjReplace(interp, res, 0, 1, 1, xv);
2269
2270		Tcl_SetObjResult (interp, res);
2271		return TCL_ERROR;
2272	    }
2273	}
2274    }
2275
2276    # # ## ### ##### ######## #############
2277    ## Object command, method dispatch.
2278
2279    critcl::ccode {
2280	static int parser_objcmd (ClientData cd, Tcl_Interp* interp, int objc, Tcl_Obj* CONST* objv)
2281	{
2282	    RDE_PARAM p = (RDE_PARAM) cd;
2283	    int m, res;
2284
2285	    static CONST char* methods [] = {
2286		"destroy", "parse", "parset", NULL
2287	    };
2288	    enum methods {
2289		M_DESTROY, M_PARSE, M_PARSET
2290	    };
2291
2292	    if (objc < 2) {
2293		Tcl_WrongNumArgs (interp, objc, objv, "option ?arg arg ...?");
2294		return TCL_ERROR;
2295	    } else if (Tcl_GetIndexFromObj (interp, objv [1], methods, "option",
2296					    0, &m) != TCL_OK) {
2297		return TCL_ERROR;
2298	    }
2299
2300	    /* Dispatch to methods. They check the #args in
2301	     * detail before performing the requested
2302	     * functionality
2303	     */
2304
2305	    switch (m) {
2306		case M_DESTROY:
2307		    if (objc != 2) {
2308			Tcl_WrongNumArgs (interp, 2, objv, NULL);
2309			return TCL_ERROR;
2310		    }
2311
2312		Tcl_DeleteCommandFromToken(interp, (Tcl_Command) rde_param_query_clientdata (p));
2313		return TCL_OK;
2314
2315		case M_PARSE:	res = parser_PARSE  (p, interp, objc, objv); break;
2316		case M_PARSET:	res = parser_PARSET (p, interp, objc, objv); break;
2317		default:
2318		/* Not coming to this place */
2319		ASSERT (0,"Reached unreachable location");
2320	    }
2321
2322	    return res;
2323	}
2324    }
2325
2326    # # ## ### ##### ######## #############
2327    # Class command, i.e. object construction.
2328
2329    critcl::ccommand PARSER_critcl {dummy interp objc objv} {
2330	/*
2331	 * Syntax: No arguments beyond the name
2332	 */
2333
2334	RDE_PARAM   parser;
2335	CONST char* name;
2336	Tcl_Obj*    fqn;
2337	Tcl_CmdInfo ci;
2338	Tcl_Command c;
2339
2340#define USAGE "?name?"
2341
2342	if ((objc != 2) && (objc != 1)) {
2343	    Tcl_WrongNumArgs (interp, 1, objv, USAGE);
2344	    return TCL_ERROR;
2345	}
2346
2347	if (objc < 2) {
2348	    name = PARSERnewName (interp);
2349	} else {
2350	    name = Tcl_GetString (objv [1]);
2351	}
2352
2353	if (!Tcl_StringMatch (name, "::*")) {
2354	    /* Relative name. Prefix with current namespace */
2355
2356	    Tcl_Eval (interp, "namespace current");
2357	    fqn = Tcl_GetObjResult (interp);
2358	    fqn = Tcl_DuplicateObj (fqn);
2359	    Tcl_IncrRefCount (fqn);
2360
2361	    if (!Tcl_StringMatch (Tcl_GetString (fqn), "::")) {
2362		Tcl_AppendToObj (fqn, "::", -1);
2363	    }
2364	    Tcl_AppendToObj (fqn, name, -1);
2365	} else {
2366	    fqn = Tcl_NewStringObj (name, -1);
2367	    Tcl_IncrRefCount (fqn);
2368	}
2369	Tcl_ResetResult (interp);
2370
2371	if (Tcl_GetCommandInfo (interp,
2372				Tcl_GetString (fqn),
2373				&ci)) {
2374	    Tcl_Obj* err;
2375
2376	    err = Tcl_NewObj ();
2377	    Tcl_AppendToObj    (err, "command \"", -1);
2378	    Tcl_AppendObjToObj (err, fqn);
2379	    Tcl_AppendToObj    (err, "\" already exists", -1);
2380
2381	    Tcl_DecrRefCount (fqn);
2382	    Tcl_SetObjResult (interp, err);
2383	    return TCL_ERROR;
2384	}
2385
2386	parser = rde_param_new (sizeof(p_string)/sizeof(char*), (char**) p_string);
2387	c = Tcl_CreateObjCommand (interp, Tcl_GetString (fqn),
2388				  parser_objcmd, (ClientData) parser,
2389				  PARSERdeleteCmd);
2390	rde_param_clientdata (parser, (ClientData) c);
2391	Tcl_SetObjResult (interp, fqn);
2392	Tcl_DecrRefCount (fqn);
2393	return TCL_OK;
2394    }
2395
2396    ##
2397    # # ## ### ##### ######## #############
2398}
2399
2400# # ## ### ##### ######## ############# #####################
2401## Ready (Note: Our package provide is at the top).
2402return
2403