|
|
1.1 ! root 1: /******************************************************************* ! 2: * * ! 3: * File: CIFPLOT/scanner.c * ! 4: * Written by Dan Fitzpatrick * ! 5: * copyright 1980 -- Regents of the University of California * ! 6: * * ! 7: ********************************************************************/ ! 8: ! 9: #include "lextable.h" ! 10: #include "scanner.h" ! 11: ! 12: /* LexState holds the state of the scanner */ ! 13: int LexState = 0; ! 14: /* LexChar hold any character that must be remembered */ ! 15: char LexChar; ! 16: /* The level of nesting in comments */ ! 17: int CmtLevel; ! 18: ! 19: scanner() { ! 20: ! 21: upToDate = 1; ! 22: TokenLine = LineNo; ! 23: TokenChar = CharNo; ! 24: while(1) ! 25: /* The scanner is a finite state machine with 4 states ! 26: * State 0 reads input and return appropriate value. ! 27: * State 1 reads blanks and output just one blank unless ! 28: * the next character is a semicolon, when it ouputs ! 29: * just the semi-colon. If the next character is not a ! 30: * semicolon it goes into state 2 which holds the character ! 31: * till the next call, then moves into state 3 to output ! 32: * the appropriate value. */ ! 33: switch(LexState) { ! 34: case 0: ! 35: yylval = input(); ! 36: case 3: ! 37: LexState = 0; ! 38: switch(CharClass[yylval]) { ! 39: ! 40: case DIGIT: ! 41: return(yylval); ! 42: case LETTER: ! 43: return(yylval); ! 44: case EOF: ! 45: /* Return a 0 if nothing more to read */ ! 46: if(Next() == 1) ! 47: return(0); ! 48: break; ! 49: case STARTCOMMENT: ! 50: CmtLevel = 1; ! 51: while(CmtLevel) ! 52: switch(CharClass[input()]) { ! 53: case STARTCOMMENT: ! 54: CmtLevel++; ! 55: break; ! 56: case ENDCOMMENT: ! 57: if(--CmtLevel == 0 && RetCmt) { ! 58: yylval = MakeComment(); ! 59: return(COMMENT_COMMAND); ! 60: } ! 61: break; ! 62: case EOF: ! 63: if(Next() == 1) { ! 64: Error("Non-Terminated Comment",FATAL); ! 65: return(0); ! 66: } ! 67: else ! 68: Error("Comment crosses file boundary",WARNING); ! 69: break; ! 70: } ! 71: case BLANK: ! 72: if(SendAll) ! 73: switch(yylval) { ! 74: case '"': ! 75: return(yylval); ! 76: case ' ': ! 77: case '\t': ! 78: case '\n': ! 79: return(BLANK); ! 80: default: ! 81: return(OTHERCHAR); ! 82: ! 83: } ! 84: LexState = 1; ! 85: /* fall through to State 1 */ ! 86: break; ! 87: case ENDCOMMENT: ! 88: Error("Unmatched ')' Ignored",RECOVERABLE); ! 89: break; ! 90: default: ! 91: Error("Unknown Character Class encountered in scanner",INTERNAL); ! 92: } ! 93: case 1: ! 94: /* Tight loop to read blanks */ ! 95: while(CharClass[yylval=input()] == BLANK); ! 96: ! 97: if(';' == yylval) { ! 98: LexState = 0; ! 99: return(yylval); ! 100: } ! 101: if('(' == yylval) { ! 102: LexState = 3; ! 103: break; ! 104: } ! 105: LexState = 2; ! 106: LexChar = yylval; ! 107: return(BLANK); ! 108: case 2: ! 109: LexState = 3; ! 110: yylval = LexChar; ! 111: break; ! 112: default: ! 113: Error("Scanner is in unknown state",INTERNAL); ! 114: } ! 115: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.