4 * Copyright (c) 2002, Venkatesh Prasad Ranganath and Darren Hiebert
6 * This source code is released for free distribution under the terms of the
7 * GNU General Public License.
9 * This module contains functions for generating tags for SML language files.
15 #include "general.h" /* must always come first */
42 static kindOption SmlKinds
[] = {
43 { TRUE
, 'e', "exception", "exception declarations" },
44 { TRUE
, 'f', "function", "function definitions" },
45 { TRUE
, 'c', "functor", "functor definitions" },
46 { TRUE
, 's', "signature", "signature declarations" },
47 { TRUE
, 'r', "structure", "structure declarations" },
48 { TRUE
, 't', "type", "type definitions" },
49 { TRUE
, 'v', "value", "value bindings" }
55 } SmlKeywordTypes
[] = {
56 { "abstype", K_TYPE
},
58 { "datatype", K_TYPE
},
59 { "exception", K_EXCEPTION
},
60 { "functor", K_FUNCTOR
},
61 { "fun", K_FUNCTION
},
62 { "signature", K_SIGNATURE
},
63 { "structure", K_STRUCTURE
},
68 static unsigned int CommentLevel
= 0;
71 * FUNCTION DEFINITIONS
74 static void makeSmlTag (smlKind type
, vString
*name
)
77 initTagEntry (&tag
, vStringValue (name
));
78 tag
.kindName
= SmlKinds
[type
].name
;
79 tag
.kind
= SmlKinds
[type
].letter
;
83 static const unsigned char *skipSpace (const unsigned char *cp
)
85 while (isspace ((int) *cp
))
90 static boolean
isIdentifier (int c
)
92 boolean result
= FALSE
;
93 /* Consider '_' as an delimiter to aid user in tracking it's usage. */
94 const char *const alternateIdentifiers
= "!%&$#+-<>=/?@\\~'^|*_";
97 else if (c
!= '\0' && strchr (alternateIdentifiers
, c
) != NULL
)
102 static const unsigned char *parseIdentifier (
103 const unsigned char *cp
, vString
*const identifier
)
105 boolean stringLit
= FALSE
;
106 vStringClear (identifier
);
107 while (*cp
!= '\0' && (!isIdentifier ((int) *cp
) || stringLit
))
111 if (oneback
== '(' && *cp
== '*' && stringLit
== FALSE
)
116 if (*cp
== '"' && oneback
!= '\\')
121 if (stringLit
&& *cp
== '"' && oneback
!= '\\')
124 if (strcmp ((const char *) cp
, "") == 0 || cp
== NULL
)
127 while (isIdentifier ((int) *cp
))
129 vStringPut (identifier
, (int) *cp
);
132 vStringTerminate (identifier
);
136 static smlKind
findNextIdentifier (const unsigned char **cp
)
138 smlKind result
= K_NONE
;
139 vString
*const identifier
= vStringNew ();
140 unsigned int count
= sizeof (SmlKeywordTypes
) / sizeof (SmlKeywordTypes
[0]);
142 *cp
= parseIdentifier (*cp
, identifier
);
143 for (i
= 0 ; i
< count
&& result
== K_NONE
; ++i
)
145 const char *id
= vStringValue (identifier
);
146 if (strcmp (id
, SmlKeywordTypes
[i
].keyword
) == 0)
147 result
= SmlKeywordTypes
[i
].kind
;
152 static void findSmlTags (void)
154 vString
*const identifier
= vStringNew ();
155 const unsigned char *line
;
156 smlKind lastTag
= K_NONE
;
158 while ((line
= fileReadLine ()) != NULL
)
160 const unsigned char *cp
= skipSpace (line
);
164 if (CommentLevel
!= 0)
166 cp
= (const unsigned char *) strstr ((const char *) cp
, "*)");
175 foundTag
= findNextIdentifier (&cp
);
176 if (foundTag
!= K_NONE
)
179 cp
= parseIdentifier (cp
, identifier
);
180 if (foundTag
== K_AND
)
181 makeSmlTag (lastTag
, identifier
);
184 makeSmlTag (foundTag
, identifier
);
188 if (strstr ((const char *) cp
, "(*") != NULL
)
191 cp
= (const unsigned char *) strstr ((const char *) cp
, "*)");
195 } while (cp
!= NULL
&& strcmp ((const char *) cp
, "") != 0);
197 vStringDelete (identifier
);
200 extern parserDefinition
*SmlParser (void)
202 static const char *const extensions
[] = { "sml", "sig", NULL
};
203 parserDefinition
*def
= parserNew ("SML");
204 def
->kinds
= SmlKinds
;
205 def
->kindCount
= KIND_COUNT (SmlKinds
);
206 def
->extensions
= extensions
;
207 def
->parser
= findSmlTags
;
211 /* vi:set tabstop=4 shiftwidth=4: */