BRoutine Analyzer Source File Analysis - Source Code

Source Code

„Go to: Contents; Previous section.




ARoutine Analyzer Source File Analysis - bliparse.c7

bliparse.c Source Code

Go to: Contents; Previous section; Beginning of section; Next file in section.

Q

Routines In This File (Alphabetical)



 Line Name
----- ----+  561 bliss_parser(  309 get_token(  250 iskeyword.  211 new_source_line&  282 ustrcpy


BEGINNING OF FILE


V     1: /****************************************************************************/     2: /*									    */1     3: /*  FACILITY:	Routine Analyzer					    */     4: /*									    */4     5: /*  MODULE:	BLISS Language Parser					    */     6: /*									    */O     7: /*  AUTHOR:	Steve Branam, Network Product Support Group, Digital	    */>     8: /*		Equipment Corporation, Littleton, MA, USA.		    */     9: /*									    */V    10: /*  DESCRIPTION: This module contains the source parser for BLISS language  */S    11: /*  source files. Note that this particular implementation is a very	    */V    12: /*  rudimentary state-driven parser. While it is reasonably functional, it  */V    13: /*  is possible that it may become confused by unusual but otherwise valid  */,    14: /*  language constructs.						    */    15: /*									    */*    16: /*  REVISION HISTORY:							    */    17: /*									    */7    18: /*  V0.1-00 19-SEP-1994 Steve Branam					    */    19: /*									    */(    20: /*	Original version.						    */    21: /*									    */V    22: /****************************************************************************/    23:      24: #include <stdio.h>     25: #include <ctype.h>    26: #include "ranalyzer.h"    27: #include "parser.h"    28: +    29: #define BLISS_KEYWORD_BEGIN	"BEGIN"'    30: #define BLISS_KEYWORD_END	"END"/    31: #define BLISS_KEYWORD_ROUTINE	"ROUTINE"/    32: #define BLISS_KEYWORD_FORWARD	"FORWARD"1    33: #define BLISS_KEYWORD_EXTERNAL	"EXTERNAL"?    34: #define MAX_QUOTED_LEN		1024		/* Just a guess...	    */    35:     36: typedef enum	    37: {    38:     NO_MACRO,    39:     IN_MACRO    40: } c_macro_states;    41:     42: typedef enum	    43: {    44:     FIND_START,    45:     FIND_END_ALNUM,    46:     FIND_END_NUMBER,    47:     FIND_END_SPACE,    48:     FIND_END_SQUOTED,&    49:     FIND_END_TRAILING_COMMENT,%    50:     FIND_END_EMBEDDED_COMMENT    51: } bliss_scanner_states;    52:     53: typedef enum	    54: {    55:     FIND_ROUTINE,    56:     FIND_IDENT,    57:     FIND_DEF_EQUALS,    58:     FIND_DEF_RPAREN,    59:     FIND_DEF_ATTR,    60:     FIND_LBRACE,    61:     IN_ROUTINE,    62:     FIND_REF_LPAREN    63: } bliss_parser_states;    64:     65: static char    66: 	*mPSNames[] = {    67: 	    "FIND_ROUTINE",    68: 	    "FIND_IDENT",    69: 	    "FIND_DEF_EQUALS",    70: 	    "FIND_DEF_RPAREN",    71: 	    "FIND_DEF_ATTR",    72: 	    "FIND_LBRACE",    73: 	    "IN_ROUTINE",    74: 	    "FIND_REF_LPAREN"    75: 	};    76:     77: typedef enum	    78: {0    79:     END_BLISS_SOURCE,				/* EOF			    */'    80:     LPAREN,					/* '('			    */'    81:     RPAREN,					/* ')'			    */.    82:     BEGIN_BLOCK,				/* "BEGIN"		    */+    83:     END_BLOCK,					/* "END"		    */1    84:     ROUTINE_DECL,				/* "ROUTINE"		    */1    85:     FORWARD_DECL,				/* "FORWARD"		    */3    86:     EXTERNAL_DECL,				/* "EXTERNAL"		    */'    87:     EQUALS,					/* '='			    */&    88:     COLON,					/* ':'			    */*    89:     SEMICOLON,					/* ';'			    */    90:     IDENTIFIER,    91:     KEYWORD,    92:     MACBEGIN,    93:     SPACE,    94:     OTHER    95: } bliss_token_types;    96:     97: static	char+    98: 	*keywords[] = { "addressing_mode",    99: 			"align",   100: 			"always",   101: 			"and",   102: 			"begin",   103: 			"bind",   104: 			"bit",   105: 			"builtin",   106: 			"by",   107: 			"byte",   108: 			"case",   109: 			"codecomment",   110: 			"compiletime",   111: 			"decr",   112: 			"decru",   113: 			"do",   114: 			"else",   115: 			"eludom",   116: 			"enable",   117: 			"eql",   118: 			"eqla",   119: 			"eqlu",   120: 			"eqv",   121: 			"exitloop",   122: 			"external",   123: 			"field",   124: 			"forward",   125: 			"from",   126: 			"geq",   127: 			"geqa",   128: 			"gequ",   129: 			"global",   130: 			"gtr",   131: 			"gtra",   132: 			"gtru",   133: 			"if",   134: 			"incr",   135: 			"incra",   136: 			"incru",   137: 			"initial",   138: 			"inrange",   139: 			"iopage",   140: 			"keywordmacro",   141: 			"label",   142: 			"leave",   143: 			"leq",   144: 			"leqa",   145: 			"lequ",   146: 			"library",   147: 			"linkage",   148: 			"literal",   149: 			"local",   150: 			"long",   151: 			"lss",   152: 			"lssa",   153: 			"lssu",   154: 			"macro",   155: 			"map",   156: 			"mod",   157: 			"module",   158: 			"neq",   159: 			"neqa",   160: 			"nequ",   161: 			"not",   162: 			"novalue",   163: 			"of",   164: 			"or",   165: 			"otherwise",   166: 			"outrange",   167: 			"own",   168: 			"plit",   169: 			"preset",   170: 			"psect",   171: 			"record",   172: 			"ref",   173: 			"register",   174: 			"rep",   175: 			"require",   176: 			"return",   177: 			"routine",   178: 			"select",   179: 			"selecta",   180: 			"selectone",   181: 			"selectonea",   182: 			"selectoneu",   183: 			"selectu",   184: 			"set",   185: 			"show",   186: 			"signed",   187: 			"stacklocal",   188: 			"structure",   189: 			"switches",   190: 			"tes",   191: 			"then",   192: 			"to",   193: 			"undeclare",   194: 			"unsigned",   195: 			"until",   196: 			"uplit",   197: 			"volatile",   198: 			"weak",   199: 			"while",   200: 			"with",   201: 			"word",   202: 			"xor",   203: 			NULL };   204: :   205: static  int				    /* Statement char count.	    */   206: 	statement;8   207: static  int				    /* Comment char count.	    */   208: 	comment;   209: V   210: /*************************************************************************++*/

hROUTINE new_source_line. Go to: mNext routine in file; Routines in this file.



$   211: static void new_source_line(I   212: /* Updates source line counters when a new line is found.		    */   213:    214:     SOURCEFILE   215: 	    *aSourceRecord*   216: 		/* (MODIFY, BY ADDR):					    */B   217: 		/* Source file information record. The line count	    */2   218: 		/* statistics will be updated.				    */   219: (   220: )	/* No return value						    */O   221: 	/*****************************************************************--*/   222: 	   223: {   224:     /*F   225:     ** Classify the source line just completed as either mixedQ   226:     ** statements/comments, statements only, comments only, or blank, and@   227:     ** increment the appropriate source record counters.   228:     */   229:     /   230:     if (statement && comment) {)   231: 	inc_source_mixed(aSourceRecord);
   232:     }    233:     else if (statement){.   234: 	inc_source_statements(aSourceRecord);
   235:     }c   236:     else if (comment) {<,   237: 	inc_source_comments(aSourceRecord);
   238:     }n   239:     else {)   240: 	inc_source_empty(aSourceRecord);c
   241:     }>   242:     B   243:     statement = 0;			    /* Reset counters for next	    */2   244:     comment   = 0;			    /* line.			    */   245: )   246:     new_list_line(aSourceRecord);n	   247: }s
MEND new_source_line. Go to: Beginning of routine.

0



n   248: V   249: /*************************************************************************++*/

bROUTINE iskeyword. Go to: mNext routine in file; Routines in this file.

8

y   250: static int iskeyword(5V   251: /* Determines whether or not an alphanumeric token is a source language	    */!   252: /* keyword.								    */   253: !   254:     char    *aKeywords[],*,   255: 	    /* (READ, BY ADDR):						    */O   256: 	    /* List of known source language keyword string pointers, in    */ E   257: 	    /* alphabetical order, terminated by NULL entry.		    */    258:    259:     char    *aToken7,   260: 	    /* (READ, BY ADDR):						    */1   261: 	    /* Token string to check.					    */    262: 4   263: )	/* Returns status of comparison:				    *//   264: 	/*	1   - Token is a keyword.				    */n3   265: 	/*	0   - Token is not a keyword.				    */*O   266: 	/*****************************************************************--*/2   267: 	   268: {t?   269:     int	    cmpstat;			    /* Comparison status.	    */3:   270:     int	    length;			    /* Token length.		    */   271: $   272:     length = strlen(aToken);%   273:     while (*aKeywords != NULL ;   274: 	&& (cmpstat = ustrncmp(*aKeywords, aToken,*4   275: 	max(length, strlen(*aKeywords)))) < 0) {   276: 	aKeywords++; 
   277:     }	   278:     return !cmpstat;	   279: }	
GEND iskeyword. Go to: Beginning of routine.

*



*   280: V   281: /*************************************************************************++*/

`ROUTINE ustrcpy. Go to: mNext routine in file; Routines in this file.



d   282: char *ustrcpy(3   283: /* Copies a string in uppercase.					    */L   284:    285:     char    *aDest,D,   286: 	    /* (WRITE, BY ADDR):					    */O   287: 	    /* Destination string buffer into which all-uppercase string    */OO   288: 	    /* will be written. It is assumed to be long enough to hold the */ F   289: 	    /* entire contents of aSrc with null termination.		    */   290:    291:     char    *aSrc -   292: 	    /* (READ, BY ADDR):  					    */EH   293: 	    /* Source string, of any case.                     		    */   294: <   295: )	/* Returns aDest, the destination buffer.			    */O   296: 	/*****************************************************************--*/    297: 	   298: {EF   299:     char    *deststr = aDest;			/* Save dest string ptr.    */   300: #   301:     while (*aSrc != '\0') {3%   302: 	*aDest++ = toupper(*aSrc++); 
   303:     }   304:     *aDest = '\0';   305:     return deststr;	   306: } 
EEND ustrcpy. Go to: Beginning of routine.

"



    307: V   308: /*************************************************************************++*/

bROUTINE get_token. Go to: mNext routine in file; Routines in this file.

_

	   309: static get_token(3V   310: /* Source file input scanner. Reads the next lexical token from the source  */A   311: /* file and accumulates source line statistics.				    */    312: !   313:     FILE    *aSourceFile, (   314: 		/* (READ, BY ADDR):					    */8   315: 		/* Source file containing C language.			    */   316:    317:     SOURCEFILE   318: 	    *aSourceRecord,*   319: 		/* (MODIFY, BY ADDR):					    */B   320: 		/* Source file information record. The line count	    */2   321: 		/* statistics will be updated.				    */   322:    323:     char    *aToken1)   324: 		/* (WRITE, BY ADDR):					    */25   325: 		/* String buffer to receive token.			    */   326: J   327: )	/* Returns code indicating which type of token was found:	    */B   328: 	/*     END_BLISS_SOURCE - End of the source file.		    */8   329: 	/*     LPAREN	    - Left parenthesis.				    */8   330: 	/*     RPAREN	    - Right parenthesis.			    */9   331: 	/*     BEGIN_BLOCK  - "BEGIN" keyword.				    */ 7   332: 	/*     END_BLOCK    - "END" keyword.				    */,3   333: 	/*     EQUALS	    - Equals sign.				    */5-   334: 	/*     COLON	    - Colon.					    */e4   335: 	/*     SEMICOLON    - Semi-colon.				    */A   336: 	/*     IDENTIFIER   - Routine or data identifier		    */f:   337: 	/*     KEYWORD	    - C language keyword.			    */;   338: 	/*     MACBEGIN	    - Beginning of macro.			    */91   339: 	/*     SPACE	    - Whitespace.				    */ >   340: 	/*     OTHER	    - Some other type of token.			    */O   341: 	/*****************************************************************--*/    342: 	   343: {:   344:     int	    ch;				    /* Input character.		    */?   345:     bliss_scanner_states		    /* Scanner state.		    */     346: 	    state = FIND_START;K   347:     char    *nextchar = aToken;		    /* Pointer to next char	    */".   348: 					    /* position in aToken.	    */>   349:     static c_macro_states		    /* Macro state.		    */   350: 	    macro = NO_MACRO;H   351:     int	    quoted_len;			    /* Length of quoted string, for */0   352: 					    /* catching unterminated	    */%   353: 					    /* strings.			    */H   354:     long    quoted_line;		    /* Line where literal started.  */   355:    356:     do {!   357: 	ch = fgetc(aSourceFile);"   358: 	switch (state) {,   359: 	case FIND_START:   360: 	    list_char(ch);49   361: 	    if (isalpha(ch) || ch == '_' || ch == '$') {1!   362: 		state = FIND_END_ALNUM;t   363: 		*nextchar++ = ch;h   364: 		statement++;   365: 	    }$   366: 	    else if (isdigit(ch)) {"   367: 		state = FIND_END_NUMBER;   368: 		*nextchar++ = ch;    369: 		statement++;   370: 	    }$   371: 	    else if (isspace(ch)) {   372: 		if (ch == '\n') { -   373: 		    new_source_line(aSourceRecord);    374: 		}!   375: 		state = FIND_END_SPACE;m   376: 	    }   377: 	    else {e   378: 		switch (ch) {n   379: 		case '(':h   380: 		    statement++;   381: 		    return LPAREN;   382: 		    break;   383: 		case ')':*   384: 		    statement++;   385: 		    return RPAREN;   386: 		    break;   387: 		case '=':0   388: 		    statement++;   389: 		    return EQUALS;   390: 		    break;   391: 		case ':':R   392: 		    statement++;   393: 		    return COLON;   394: 		    break;   395: 		case ';':n   396: 		    statement++;   397: 		    return SEMICOLON;s   398: 		    break;   399: 		case '\'':   400: 		    statement++;'   401: 		    state = FIND_END_SQUOTED;	   402: 		    quoted_len = 0; 7   403: 		    quoted_line = source_line(aSourceRecord);	   404: 		    break;   405: 		case '!':    406: 		    comment++;0   407: 		    state = FIND_END_TRAILING_COMMENT;   408: 		    break;   409: 		case '%':*&   410: 		    ch = fgetc(aSourceFile);   411: 		    if (ch == '(') {   412: 			list_char(ch);l-   413: 			state = FIND_END_EMBEDDED_COMMENT;/   414: 			comment += 2;   415: 		    }r   416: 		    else {#   417: 			ungetc(ch, aSourceFile);c"   418: 			state = FIND_END_ALNUM;   419: 			*nextchar++ = ch;   420: 			statement++;e   421: 		    }i   422: 		    break;   423: 		default:   424: 		    if (ch != EOF) {   425: 			*nextchar++ = ch;   426: 			*nextchar   = '\0';   427: 			statement++;l   428: 			return OTHER;   429: 		    }m   430: 		}e   431: 	    }   432: 	    break;l   433: 	case FIND_END_ALNUM:(9   434: 	    if (isalnum(ch) || ch == '_' || ch == '$') {    435: 		list_char(ch);   436: 		*nextchar++ = ch;   437: 		statement++;   438: 	    }   439: 	    else {"   440: 		ungetc(ch, aSourceFile);   441: 		*nextchar = '\0';N3   442: 		if (ustrncmp(aToken, BLISS_KEYWORD_BEGIN,iG   443: 		    max(strlen(BLISS_KEYWORD_BEGIN), strlen(aToken))) == 0) {*!   444: 		    return BEGIN_BLOCK;*   445: 		}*6   446: 		else if (ustrncmp(aToken, BLISS_KEYWORD_END,E   447: 		    max(strlen(BLISS_KEYWORD_END), strlen(aToken))) == 0) {H   448: 		    return END_BLOCK;f   449: 		}R:   450: 		else if (ustrncmp(aToken, BLISS_KEYWORD_ROUTINE,I   451: 		    max(strlen(BLISS_KEYWORD_ROUTINE), strlen(aToken))) == 0) {t"   452: 		    return ROUTINE_DECL;   453: 		}/:   454: 		else if (ustrncmp(aToken, BLISS_KEYWORD_FORWARD,I   455: 		    max(strlen(BLISS_KEYWORD_ROUTINE), strlen(aToken))) == 0) {6"   456: 		    return FORWARD_DECL;   457: 		}t;   458: 		else if (ustrncmp(aToken, BLISS_KEYWORD_EXTERNAL, I   459: 		    max(strlen(BLISS_KEYWORD_ROUTINE), strlen(aToken))) == 0) {#   460: 		    return EXTERNAL_DECL;	   461: 		}11   462: 		else if (iskeyword(keywords, aToken)) {2   463: 		    return KEYWORD;    464: 		}:   465: 		else {    466: 		    return IDENTIFIER;   467: 		}2   468: 	    }   469: 	    break;	   470: 	case FIND_END_NUMBER:   471: 	    if (isdigit(ch)) {*   472: 		list_char(ch);   473: 		*nextchar++ = ch;9   474: 		statement++;   475: 	    }   476: 	    else { "   477: 		ungetc(ch, aSourceFile);   478: 		*nextchar = '\0';    479: 		return OTHER;r   480: 	    }   481: 	    break;y   482: 	case FIND_END_SPACE:a   483: 	    if (isspace(ch)) {s   484: 		list_char(ch);   485: 		if (ch == '\n') {&-   486: 		    new_source_line(aSourceRecord);	   487: 		}    488: 	    }   489: 	    else {"   490: 		ungetc(ch, aSourceFile);   491: 		*nextchar = '\0';A   492: 		return SPACE;2   493: 	    }   494: 	    break;*   495: 	case FIND_END_SQUOTED:*   496: 	    list_char(ch);H2   497: 	    if (quoted_len++ == MAX_QUOTED_LEN) {   498: 		printf(0H   499: 		"WARNING: Suspected unterminated string literal at line %d\n",   500: 		    quoted_line);_   501: 	    }   502: 	    if (ch == '\'') {"   503: 		ch = fgetc(aSourceFile);   504: 		if (ch == '\'') {	   505: 		    *nextchar++ = ch;h   506: 		    statement++;   507: 		    list_char(ch);   508: 		}    509: 		else {&   510: 		    ungetc(ch, aSourceFile);   511: 		}   512: 		*nextchar++ = ch;e   513: 		*nextchar   = '\0';u   514: 		statement++;   515: 		return OTHER;t   516: 	    }#   517: 	    else if (ch == '\n') { )   518: 		new_source_line(aSourceRecord);R   519: 	    }   520: 	    else {    521: 		statement++;   522: 	    }   523: 	    break; (   524: 	case FIND_END_TRAILING_COMMENT:   525: 	    list_char(ch);    526: 	    if (ch == '\n') {)   527: 		new_source_line(aSourceRecord);*   528: 		state = FIND_START;   529: 	    }   530: 	    else {	   531: 		comment++;   532: 	    }   533: 	    break;l(   534: 	case FIND_END_EMBEDDED_COMMENT:   535: 	    list_char(ch);    536: 	    if (ch == ')') {;"   537: 		ch = fgetc(aSourceFile);   538: 		if (ch == '%') {   539: 		    list_char(ch);!   540: 		    state = FIND_START;   541: 		    comment += 2;*   542: 		}*   543: 		else {&   544: 		    ungetc(ch, aSourceFile);   545: 		    comment++;   546: 		}T   547: 	    }#   548: 	    else if (ch == '\n') {e)   549: 		new_source_line(aSourceRecord);N   550: 	    }   551: 	    else {u   552: 		comment++;   553: 	    }   554: 	    break;
   555: 	}    556:     } while (ch != EOF);$   557:     return END_BLISS_SOURCE;	   558: }f
GEND get_token. Go to: Beginning of routine.





    559: V   560: /*************************************************************************++*/

eROUTINE bliss_parser. Go to: *mNext routine in file; Routines in this file.

*

t&   561: language_element bliss_parser(V   562: /* Parses BLISS source language statements, looking for routine definition  */T   563: /* begin and end, and routine references. Retrieves the next language	    */2   564: /* element in the source file.						    */   565: /*									    */EV   566: /* Note that this version is a very simple-minded parser, and has several   */U   567: /* limitations.  It is not able to identify function pointer usages as	    */ V   568: /* routine references. It may also be confused by other legal constructs.   */   569: !   570:     FILE    *aSourceFile,	(   571: 		/* (READ, BY ADDR):					    */H   572: 		/* Source file containing BLISS language. Must be opened by */    573: 		/* caller.						    */   574:    575:     SOURCEFILE   576: 	    *aSourceRecord,(   577: 		/* (READ, BY ADDR):					    */5   578: 		/* Source file information record.			    *//   579:    580:     char    *aElement,)   581: 		/* (WRITE, BY ADDR):					    */ H   582: 		/* String buffer that will receive the recognized source    */)   583: 		/* language element.					    */3   584:     585:     long    *aSourceLine)   586: 		/* (WRITE, BY ADDR):					    */nH   587: 		/* Buffer that will receive the line number of aElement.    */   588: N   589: )	/* Returns one of the following values indicating the type of	    */2   590: 	/* element output in aElement:					    */K   591: 	/*      PARSE_ERROR	    - An error was detected in the input    */A%   592: 	/*			      stream.				    */	H   593: 	/*	END_OF_SOURCE	    - The normal end of file was found.	    */J   594: 	/*	ROUTINE_DEF_BEGIN   - The beginning of a routine definition */'   595: 	/*			      was found.			    */tG   596: 	/*	ROUTINE_DEF_END	    - The end of the current routine	    */"1   597: 	/*			      definition was found.		    */AF   598: 	/*	ROUTINE_REF	    - A routine reference (call) was found. */O   599: 	/*****************************************************************--*/    600: 	   601: {tD   602:     static bliss_parser_states		    /* Parser state.		    */"   603: 	    state = FIND_ROUTINE;;   604:     static int				    /* Nested block level.	    */}   605: 	    blevel;A   606:     static char				    /* Name of current routine.	    */o.   607: 	    curdefname[MAX_ROUTINE_NAME + 1];D   608:     int	    plevel;			    /* Nested parenthesis level.    */C   609:     bliss_token_types			    /* Type of source token.	    */+   610: 	    tokentype;LR   611:     char    token[MAX_ROUTINE_NAME + 1];    /* Source token buffer.	    */I   612:     int	    forward_flag = 0;		    /* Indicates FORWARD or	    */81   613: 					    /* EXTERNAL keyword seen.	    */   614:    615:     /*+									    */U   616:     /*	This function operates as a state machine. The states represent the */5T   617:     /*	various tokens expected next in the token stream, according to	    */U   618:     /*	BLISS syntax. Whenever a routine definition beginning or end, or    */IU   619:     /*	routine reference, is recognized, the parser returns to the caller. */nT   620:     /*	However, context is maintained between calls to the parser via	    */2   621:     /*	static state variables.						    */   622:     /*-									    */   623:    624:     do {B   625: 	tokentype = get_token(aSourceFile, aSourceRecord, token);   626: 	switch (state) {	   627: 	case FIND_ROUTINE:M>   628: 	    if (forward_flag && tokentype != SPACE) {   629: 		forward_flag = 0;h   630: 	    }2   631: 	    else if (tokentype == ROUTINE_DECL) {4   632: 		*aSourceLine = source_line(aSourceRecord);$   633: 		change_pstate(FIND_IDENT);   634: 	    }P   635: 	    else if (tokentype == FORWARD_DECL || tokentype == EXTERNAL_DECL) {   636: 		forward_flag = 1;l   637: 		trace_msg(N   638: 	    "\nTRACE: Parser will ignore token after FORWARD or EXTERNAL\n");   639: 	    }   640: 	    break;    641: 	case FIND_IDENT: +   642: 	    if (tokentype == IDENTIFIER) {;#   643: 		ustrcpy(aElement, token);7)   644: 		change_pstate(FIND_DEF_EQUALS);    645: 	    }6   646: 	    else if (tokentype == END_BLISS_SOURCE) {6   647: 		printf("ERROR: Unexpected end of file %s\n",*   648: 		    source_name(aSourceRecord));   649: 		return PARSE_ERROR;*   650: 	    }+   651: 	    else if (tokentype != SPACE) {	&   652: 		change_pstate(FIND_ROUTINE);   653: 	    }   654: 	    break;K   655: 	case FIND_DEF_EQUALS:'   656: 	    if (tokentype == EQUALS) {$   657: 		change_pstate(IN_ROUTINE);   658: 		block_level_zero();N%   659: 		ustrcpy(curdefname, token);O#   660: 		return ROUTINE_DEF_BEGIN;t   661: 	    },   662: 	    else if (tokentype == LPAREN) {)   663: 		change_pstate(FIND_DEF_RPAREN);W   664: 		paren_level_zero();B   665: 	    }+   666: 	    else if (tokentype == COLON) { '   667: 		change_pstate(FIND_DEF_ATTR);4K   668: puts("*** WARNING: FIND_DEF_ATTR state not fully implemented ***");t   669: 	    }+   670: 	    else if (tokentype != SPACE) {0&   671: 		change_pstate(FIND_ROUTINE);   672: 	    }   673: 	    break;y   674: 	case FIND_DEF_RPAREN:'   675: 	    if (tokentype == RPAREN) {    676: 		if (plevel) {e    677: 		    paren_level_dec();   678: 		}   679: 		else {-   680: 		    change_pstate(FIND_DEF_EQUALS);    681: 		}c   682: 	    },   683: 	    else if (tokentype == LPAREN) {   684: 		paren_level_inc();   685: 	    }   686: 	    break;4   687: 	case FIND_DEF_ATTR:   688: puts(token);	 '   689: 	    if (tokentype == EQUALS) { $   690: 		change_pstate(IN_ROUTINE);   691: 		block_level_zero(); %   692: 		ustrcpy(curdefname, token);t#   693: 		return ROUTINE_DEF_BEGIN;    694: 	    }   695: 	    break;u   696: 	case IN_ROUTINE:,   697: 	    if (tokentype == BEGIN_BLOCK) {   698: 		block_level_inc();   699: 	    }/   700: 	    else if (tokentype == END_BLOCK) {    701: 		block_level_dec();   702: 	    }/   703: 	    else if (tokentype == SEMICOLON) {7   704: 		if (blevel == 0) {!   705: 		    trace_blmsg(BLEND);*   706: 		    change_pstate(FIND_ROUTINE);8   707: 		    *aSourceLine = source_line(aSourceRecord);,   708: 		    ustrcpy(aElement, curdefname);%   709: 		    return ROUTINE_DEF_END;   710: 		}(   711: 	    }0   712: 	    else if (tokentype == IDENTIFIER) {#   713: 		ustrcpy(aElement, token);h4   714: 		*aSourceLine = source_line(aSourceRecord);)   715: 		change_pstate(FIND_REF_LPAREN);    716: 	    }6   717: 	    else if (tokentype == END_BLISS_SOURCE) {6   718: 		printf("ERROR: Unexpected end of file %s\n",*   719: 		    source_name(aSourceRecord));   720: 		return PARSE_ERROR;    721: 	    }   722: 	    break;    723: 	case FIND_REF_LPAREN:&   724: 	    if (tokentype != SPACE) {'   725: 		if (tokentype == END_BLOCK) {     726: 		    block_level_dec();   727: 		}{$   728: 		change_pstate(IN_ROUTINE);   729: 	    }'   730: 	    if (tokentype == LPAREN) {    731: 		return ROUTINE_REF;o   732: 	    }   733: 	    break; 
   734: 	}4   735:     } while (tokentype != END_BLISS_SOURCE);(   736:     change_pstate(FIND_ROUTINE);!   737:     return END_OF_SOURCE;i	   738: }8
JEND bliss_parser. Go to: Beginning of routine.





	   739: 
END OF FILE !TOTAL: 5 routines, 104 Avg Lengthn

Go to: Contents; Previous section; Beginning of section; Next file in section.