%{ /* s2l.l 1.2 85/02/04 */ /* scanner for "scribe" documents. * * copyright (c) 1984 by Van Jacobson, Lawrence Berkeley Laboratory * This program may be freely redistributed but not for profit. This * comment must remain in the program or any derivative. */ static char bstack[256]; /* the type of closing bracket we want */ static int bsp = 0; /* "bracket" stack pointer */ char matching(); %} WS [ \t]* LB ("("|"["|"{"|"<"|\'|\"|\`) RB (")"|"]"|"}"|">"|\'|\"|\') %START CS BS B C %% @[bB][lL][aA][nN][kK][sS][pP][aA][cC][eE]/{LB} { BEGIN BS; if ( lastsym=lookup(yytext) ) return (lastsym->s_type); fprintf(stderr,"lex botch: keyword %s\n", yytext ); exit(1); } @[bB][eE][gG][iI][nN]{WS}{LB} return(get_env_name()); @[eE][nN][dD]{WS}{LB} { get_env_name(); return(END_ENV); } @[a-zA-Z0-9]+/{WS}{LB} { BEGIN CS; if ( !(lastsym=lookup(yytext)) ) { if ( kflag ) fprintf(stderr,"unknown keyword %s\n", yytext ); lastsym = enter( yytext, KW_REP, &yytext[1] ); } return (lastsym->s_type); } @[a-zA-Z0-9]+ return(COMMAND); @\+/{WS}{LB} { BEGIN CS; return(SUP); } @\-/{WS}{LB} { BEGIN CS; return(SUB); } {WS} ; {LB} { bstack[++bsp] = matching(*yytext); BEGIN C; return(LBRACK); } {WS} ; {LB} { bstack[++bsp] = matching(*yytext); BEGIN B; return(LBRACK); } {RB} { if ( bstack[bsp] == *yytext ) { if ( --bsp <= 0 ) BEGIN 0; return(RBRACK); } return( (*yytext=='}'||*yytext=='"')? *yytext : CHAR ); } [iI][nN][cC][hH][eE][sS] { return(INCHES); } @\\ return(TAB); @> return(RJUST); @= return(CENTER); @\\{WS}@= return(CENTER); @"^" return(SETTAB); @\\{WS}@=/{WS}\n ; @=/{WS}\n ; @\\/{WS}\n ; @; ; @~ return(STILDE); @_ return(HYPHEN); @" " return(NPSPACE); @@ return('@'); @"*" return(LBREAK); @\.[ \t]+ return(POINT); @\.{WS}/\n return(POINT); [<>|{}#$%&~_^\\"] return(*yytext); . return(CHAR); ^[ ]*\n { inputline++; return(BLANKLINE); } [ ]*\n { inputline++; return('\n'); } %% yywrap() { return (1); } /* get the "name" part of an environment spec & discard any optional * parameters. The name is added to the symbol table if it isn't * already there. At the time we call this routine, we've matched * either "@begin{LB}" or "@end{LB}". We gobble input until we find * the matching right bracket. */ get_env_name() { char ename[128]; char c; char *nm=ename; char mb = matching( yytext[yyleng-1] ); /* get the name */ while ( isalnum( c=input() ) ) *nm++ = c; *nm = '\0'; /* discard everything else up to the closing bracket */ while ( c != mb ) c = input(); /* lookup and/or add the env name */ if ( ! (lastsym = lookup(ename)) ) { if ( kflag ) fprintf(stderr,"unknown environment %s\n", ename ); lastsym = enter( ename, ENV_REP, ename ); } return(lastsym->s_type); } /* return the right bracket character that matches the given left bracket * character. */ char matching(lb) char lb; { switch(lb) { case '(': return(')'); case '[': return(']'); case '{': return('}'); case '<': return('>'); case '"': return('"'); case '\'': return('\''); case '`': return('\''); default: fprintf(stderr,"matching botch: '%c'\n", lb ); exit(1); } }