represent input tokens in a way that doesn't clash with NULL
This commit is contained in:
parent
e504c6fc36
commit
16f933013a
1 changed files with 15 additions and 11 deletions
|
|
@ -17,8 +17,13 @@ typedef struct HCFGrammar_ {
|
||||||
HArena *arena;
|
HArena *arena;
|
||||||
} HCFGrammar;
|
} HCFGrammar;
|
||||||
|
|
||||||
typedef int HCFTerminal;
|
// mapping input bytes or end to tokens
|
||||||
static HCFTerminal end_token = -1;
|
// we want to use these, cast to void *, as elements in hashsets
|
||||||
|
// therefore we must avoid 0 as a token value because NULL means "not in set".
|
||||||
|
typedef uintptr_t HCFToken;
|
||||||
|
static inline HCFToken char_token(char c) { return (0x100 | c); }
|
||||||
|
static inline char token_char(HCFToken t) { return (0xFF & t); }
|
||||||
|
static HCFToken end_token = 0x200;
|
||||||
|
|
||||||
bool h_eq_ptr(const void *p, const void *q) { return (p==q); }
|
bool h_eq_ptr(const void *p, const void *q) { return (p==q); }
|
||||||
HHashValue h_hash_ptr(const void *p) { return (uintptr_t)p; }
|
HHashValue h_hash_ptr(const void *p) { return (uintptr_t)p; }
|
||||||
|
|
@ -210,16 +215,16 @@ HHashSet *h_first_symbol(HCFGrammar *g, const HCFChoice *x)
|
||||||
|
|
||||||
switch(x->type) {
|
switch(x->type) {
|
||||||
case HCF_END:
|
case HCF_END:
|
||||||
h_hashset_put(ret, (void *)(intptr_t)end_token);
|
h_hashset_put(ret, (void *)end_token);
|
||||||
break;
|
break;
|
||||||
case HCF_CHAR:
|
case HCF_CHAR:
|
||||||
h_hashset_put(ret, (void *)(intptr_t)x->chr);
|
h_hashset_put(ret, (void *)char_token(x->chr));
|
||||||
break;
|
break;
|
||||||
case HCF_CHARSET:
|
case HCF_CHARSET:
|
||||||
c=0;
|
c=0;
|
||||||
do {
|
do {
|
||||||
if(charset_isset(x->charset, c))
|
if(charset_isset(x->charset, c))
|
||||||
h_hashset_put(ret, (void *)(intptr_t)c);
|
h_hashset_put(ret, (void *)char_token(c));
|
||||||
} while(c++ < 255);
|
} while(c++ < 255);
|
||||||
break;
|
break;
|
||||||
case HCF_CHOICE:
|
case HCF_CHOICE:
|
||||||
|
|
@ -532,15 +537,14 @@ void h_pprint_tokenset(FILE *file, const HCFGrammar *g, const HHashSet *set, int
|
||||||
for(hte = &set->contents[i]; hte; hte = hte->next) {
|
for(hte = &set->contents[i]; hte; hte = hte->next) {
|
||||||
if(hte->key == NULL)
|
if(hte->key == NULL)
|
||||||
continue;
|
continue;
|
||||||
HCFTerminal a = (intptr_t)hte->key;
|
HCFToken a = (HCFToken)hte->key;
|
||||||
// BUG this ignores tokens with value 0!
|
|
||||||
|
|
||||||
if(a == '$')
|
if(a == end_token)
|
||||||
fputs("\\$", file);
|
|
||||||
else if(a == end_token)
|
|
||||||
fputc('$', file);
|
fputc('$', file);
|
||||||
|
else if(token_char(a) == '$')
|
||||||
|
fputs("\\$", file);
|
||||||
else
|
else
|
||||||
pprint_char(file, a);
|
pprint_char(file, token_char(a));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue