[mercury-users] Appreciate some help #3:
Thomas Charles CONWAY
conway at cs.mu.OZ.AU
Mon May 25 10:35:48 AEST 1998
tcklnbrg, you write:
> How do I define a new type that has several constraints including not
> being one of several other types?
There isn't a way. Mercury supports only discriminated union types,
not undiscriminated unions, which would be necessary (though not
sufficient on their own) for something like that.
> In particular, I have defined types: keyword; booleanliteral;
> nullliteral, etc. and now I need to define another
> type, identifier, as not a keyword, and not a booleanliteral, and not a
> null literal , and as a string with constraints on
> its form.
>
> something like:
>
> :- type keyword ---> <some enumerated words>.
> :- type booleanliteral ---> true; false.
> :- type nullliteral ---> null.
> :- type identifier ---> \+keyword, \+booleanliteral, \+nullliteral, <and
> some other string-related constraints>.
>
This sounds like tokenizing to me.
What you might want is a type like:
:- type token
---> keyword(keyword)
; true
; false
; null
; id(string) % the string is the name of the identifier
.
>
> Also, how do I convert types, as in send a string literal into something
> that takes a keyword type?
>
Well, you can't really - it a predicate expects a keyword as an argument,
then you'd better give it a keyword. What you might need to do is have
a separate predicate or function (which is semidet) that takes a string
and returns a keyword.
Here's some bits from my C tokenizer:
:- type token
---> ('+')
; ('-')
...
; ('<<=')
; ('>>=')
...
; id(string)
; int(int)
; float(float)
; string(string)
; auto
; register
; char
; extern
...
.
Then in the predicate which takes a list of characters and
returns a list of tokens:
...
;
char__is_alpha_or_underscore(C)
->
takewhile(char__is_alnum_or_underscore, Cs, WordChars, Rest),
string__from_char_list([C|WordCars], Word),
( keyword(Word, KeyWord) ->
Token = KeyWord
;
Token = id(Word)
)
;
...
:- pred keyword(string, token).
:- mode keyword(in, out) is semidet.
keyword("auto", auto).
keyword("char", char).
keyword("const", const).
keyword("extern", extern).
...
While it's not strictly necessary to convert the list of characters
into a string to do the matching process, the compiler will do more
efficient indexing on strings than lists of chars, and it's easier to
read.
Thomas
--
Thomas Conway <conway at cs.mu.oz.au>
Nail here [] for new monitor. )O+
More information about the users
mailing list