home *** CD-ROM | disk | FTP | other *** search
- %{
- (*
- * scan.l
- *
- * lex input file for pascal scanner
- *
- * extensions: to ways to spell "external" and "->" ok for "^".
- *
- * - PasLex.l: adapted to Turbo Pascal Lex 2-28-89 AG
- * Note: keywords are determined by scanning a keyword table, rather
- * than including the keyword patterns in the Lex source which is done
- * in the original version of this file. The main reason for this is,
- * that the DFA table generated from the original spec grows too large
- * to be compilable by Turbo Pascal (Lex will construct the table,
- * but Turbo Pascal puts it into the static data segment which holds
- * all typed constants and global variables, and this data segment is
- * 64 KB max.).
- *)
-
- unit PasLex;
- interface
- uses LexLib, YaccLib;
- {$I Pas.h}
- var
- infile : string;
- line_no : integer;
- function yylex : integer;
- function act_token : string;
- implementation
- const newline = #10;
- procedure commenteof;
- begin
- writeln('unexpected EOF inside comment at line ', line_no);
- end(*commenteof*);
- function is_keyword(id : string; var token : integer) : boolean;
- (* checks whether id is Pascal keyword; if so, returns corresponding
- token number in token *)
- forward;
- %}
-
- NQUOTE [^']
-
- %%
-
- var
- c : char;
- kw : integer;
-
- [a-zA-Z]([a-zA-Z0-9])* if is_keyword(yytext, kw) then
- return(kw)
- else
- return(IDENTIFIER);
-
- ":=" return(ASSIGNMENT);
- '({NQUOTE}|'')+' return(CHARACTER_STRING);
- ":" return(COLON);
- "," return(COMMA);
- [0-9]+ return(DIGSEQ);
- "." return(DOT);
- ".." return(DOTDOT);
- "=" return(EQUAL);
- ">=" return(GE);
- ">" return(GT);
- "[" return(LBRAC);
- "<=" return(LE);
- "(" return(LPAREN);
- "<" return(LT);
- "-" return(MINUS);
- "<>" return(NOTEQUAL);
- "+" return(PLUS);
- "]" return(RBRAC);
- [0-9]+"."[0-9]+ return(REALNUMBER);
- ")" return(RPAREN);
- ";" return(SEMICOLON);
- "/" return(SLASH);
- "*" return(STAR);
- "**" return(STARSTAR);
- "->" |
- "^" return(UPARROW);
-
- "(*" |
- "{" begin
- repeat
- c := input;
- case c of
- '}' : exit;
- '*' : begin
- c := input;
- if c=')' then exit else unput(c)
- end;
- newline : inc(line_no);
- #0 : commenteof;
- end;
- until false
- end;
- [ \t\f] ;
-
- \n inc(line_no);
-
- . writeln('''', yytext[1], ''' (#', ord(yytext[1]),
- '): illegal character at line ', line_no);
-
- %%
-
- function upper(id : string) : string;
- var i : integer;
- begin
- for i := 1 to length(id) do
- id[i] := upCase(id[i]);
- upper := id
- end(*upper*);
- function is_keyword(id : string; var token : integer) : boolean;
- const
- id_len = 20;
- type
- Ident = string[id_len];
- const
- (* table of Pascal keywords: *)
- no_of_keywords = 39;
- keyword : array [1..no_of_keywords] of Ident = (
- 'AND', 'ARRAY', 'BEGIN', 'CASE',
- 'CONST', 'DIV', 'DO', 'DOWNTO',
- 'ELSE', 'END', 'EXTERNAL', 'EXTERN',
- 'FILE', 'FOR', 'FORWARD', 'FUNCTION',
- 'GOTO', 'IF', 'IN', 'LABEL',
- 'MOD', 'NIL', 'NOT', 'OF',
- 'OR', 'OTHERWISE', 'PACKED', 'PROCEDURE',
- 'PROGRAM', 'RECORD', 'REPEAT', 'SET',
- 'THEN', 'TO', 'TYPE', 'UNTIL',
- 'VAR', 'WHILE', 'WITH');
- keyword_token : array [1..no_of_keywords] of integer = (
- _AND, _ARRAY, _BEGIN, _CASE,
- _CONST, _DIV, _DO, _DOWNTO,
- _ELSE, _END, _EXTERNAL, _EXTERNAL,
- (* EXTERNAL: 2 spellings (see above)! *)
- _FILE, _FOR, _FORWARD, _FUNCTION,
- _GOTO, _IF, _IN, _LABEL,
- _MOD, _NIL, _NOT, _OF,
- _OR, _OTHERWISE, _PACKED, _PROCEDURE,
- _PROGRAM, _RECORD, _REPEAT, _SET,
- _THEN, _TO, _TYPE, _UNTIL,
- _VAR, _WHILE, _WITH);
- var m, n, k : integer;
- begin
- id := upper(id);
- m := 1; n := no_of_keywords;
- while m<=n do
- begin
- k := m+(n-m) div 2;
- if id=keyword[k] then
- begin
- is_keyword := true;
- token := keyword_token[k];
- exit
- end
- else if id>keyword[k] then
- m := k+1
- else
- n := k-1
- end;
- is_keyword := false
- end(*is_keyword*);
- function act_token : string;
- begin
- act_token := yytext
- end(*act_token*);
- begin
- write('input file: ');
- readln(infile);
- line_no := 1;
- assign(yyin, infile);
- reset(yyin);
- end.