home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / compcomp / tpyacc / paslex.l < prev    next >
Text File  |  1991-04-30  |  5KB  |  163 lines

  1.  
  2. %{
  3.  
  4. (* PASLEX.L: lexical analyzer for Pascal, adapted to TP Yacc, 2-28-89 AG *)
  5.  
  6. %}
  7.  
  8. %{
  9. (*
  10.  * lex input file for pascal scanner
  11.  *
  12.  * extensions: to ways to spell "external" and "->" ok for "^".
  13.  *
  14.  *)
  15. %}
  16.  
  17. %{
  18.  
  19. (* Note: Keywords are determined by scanning a keyword table, rather
  20.    than including the keyword patterns in the Lex source which is done
  21.    in the original version of this file. I prefer this method, because
  22.    it makes the grammar itself more readable (handling case-insensitive
  23.    keywords in Lex is quite cumbersome, e.g., you will have to write
  24.    something like [Aa][Nn][Dd] to match the keyword `and'), and also
  25.    produces a more (space-) efficient analyzer (184 states and 375
  26.    transitions for the keyword pattern version, against only 40 states
  27.    and 68 transitions for the keyword table version). *)
  28.  
  29. procedure commenteof;
  30.   begin
  31.     writeln('unexpected EOF inside comment at line ', yylineno);
  32.   end(*commenteof*);
  33.  
  34. function upper(str : String) : String;
  35.   (* converts str to uppercase *)
  36.   var i : integer;
  37.   begin
  38.     for i := 1 to length(str) do
  39.       str[i] := upCase(str[i]);
  40.     upper := str
  41.   end(*upper*);
  42.  
  43. function is_keyword(id : string; var token : integer) : boolean;
  44.   (* checks whether id is Pascal keyword; if so, returns corresponding
  45.      token number in token *)
  46.   const
  47.     id_len = 20;
  48.   type
  49.     Ident = string[id_len];
  50.   const
  51.     (* table of Pascal keywords: *)
  52.     no_of_keywords = 39;
  53.     keyword : array [1..no_of_keywords] of Ident = (
  54.       'AND',       'ARRAY',     'BEGIN',    'CASE',
  55.       'CONST',     'DIV',       'DO',       'DOWNTO',
  56.       'ELSE',      'END',       'EXTERNAL', 'EXTERN',
  57.       'FILE',      'FOR',       'FORWARD',  'FUNCTION',
  58.       'GOTO',      'IF',        'IN',       'LABEL',
  59.       'MOD',       'NIL',       'NOT',      'OF',
  60.       'OR',        'OTHERWISE', 'PACKED',   'PROCEDURE',
  61.       'PROGRAM',   'RECORD',    'REPEAT',   'SET',
  62.       'THEN',      'TO',        'TYPE',     'UNTIL',
  63.       'VAR',       'WHILE',     'WITH');
  64.     keyword_token : array [1..no_of_keywords] of integer = (
  65.       _AND,        _ARRAY,      _BEGIN,     _CASE,
  66.       _CONST,      _DIV,        _DO,        _DOWNTO,
  67.       _ELSE,       _END,        _EXTERNAL,  _EXTERNAL,
  68.                                 (* EXTERNAL: 2 spellings (see above)! *)
  69.       _FILE,       _FOR,        _FORWARD,   _FUNCTION,
  70.       _GOTO,       _IF,         _IN,        _LABEL,
  71.       _MOD,        _NIL,        _NOT,       _OF,
  72.       _OR,         _OTHERWISE,  _PACKED,    _PROCEDURE,
  73.       _PROGRAM,    _RECORD,     _REPEAT,    _SET,
  74.       _THEN,       _TO,         _TYPE,      _UNTIL,
  75.       _VAR,        _WHILE,      _WITH);
  76.   var m, n, k : integer;
  77.   begin
  78.     id := upper(id);
  79.     (* binary search: *)
  80.     m := 1; n := no_of_keywords;
  81.     while m<=n do
  82.       begin
  83.         k := m+(n-m) div 2;
  84.         if id=keyword[k] then
  85.           begin
  86.             is_keyword := true;
  87.             token := keyword_token[k];
  88.             exit
  89.           end
  90.         else if id>keyword[k] then
  91.           m := k+1
  92.         else
  93.           n := k-1
  94.       end;
  95.     is_keyword := false
  96.   end(*is_keyword*);
  97.  
  98. %}
  99.  
  100. NQUOTE    [^']
  101.  
  102. %%
  103.  
  104. %{
  105.  
  106. var c  : char;
  107.     kw : integer;
  108.  
  109. %}
  110.  
  111. [a-zA-Z]([a-zA-Z0-9])*    if is_keyword(yytext, kw) then
  112.                           return(kw)
  113.                         else
  114.                           return(IDENTIFIER);
  115.  
  116. ":="            return(ASSIGNMENT);
  117. '({NQUOTE}|'')+'    return(CHARACTER_STRING);
  118. ":"            return(COLON);
  119. ","            return(COMMA);
  120. [0-9]+            return(DIGSEQ);
  121. "."            return(DOT);
  122. ".."            return(DOTDOT);
  123. "="            return(EQUAL);
  124. ">="            return(GE);
  125. ">"            return(GT);
  126. "["            return(LBRAC);
  127. "<="            return(LE);
  128. "("            return(LPAREN);
  129. "<"            return(LT);
  130. "-"            return(MINUS);
  131. "<>"            return(NOTEQUAL);
  132. "+"            return(PLUS);
  133. "]"            return(RBRAC);
  134. [0-9]+"."[0-9]+        return(REALNUMBER);
  135. ")"            return(RPAREN);
  136. ";"            return(SEMICOLON);
  137. "/"            return(SLASH);
  138. "*"            return(STAR);
  139. "**"            return(STARSTAR);
  140. "->"                |
  141. "^"            return(UPARROW);
  142.  
  143. "(*"                |
  144. "{"            begin
  145.                           repeat
  146.                 c := get_char;
  147.                 case c of
  148.                   '}' : ;
  149.                   '*' : begin
  150.                       c := get_char;
  151.                       if c=')' then exit else unget_char(c)
  152.                     end;
  153.                               #0 : begin
  154.                                      commenteof;
  155.                                      exit;
  156.                                    end;
  157.                 end;
  158.               until false
  159.                         end;
  160. [ \n\t\f]        ;
  161.  
  162. .            return(ILLEGAL);
  163.