⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scanner2.frm

📁 一个Modula-2语言分析器
💻 FRM
字号:
IMPLEMENTATION MODULE -->modulename;

(* Scanner generated by Coco/R - assuming FileIO library will be available. *)
(* Small source files only *)

IMPORT FileIO, Storage;

CONST
  noSym   = -->unknownsym; (*error token code*)
  (* not only for errors but also for not finished states of scanner analysis *)
  eof     = 32C (* MS-DOS Keyboard eof char *);
  EOF     = FileIO.EOF;
  EOL     = FileIO.CR;
  CR      = FileIO.CR;
  LF      = FileIO.LF;
  Long0   = FileIO.Long0;
  Long1   = FileIO.Long1;
  BlkSize = 64000 (*limited by maximum size one can ALLOCATE on the heap*);
TYPE
  Buffer     = POINTER TO ARRAY [0 .. BlkSize-1] OF CHAR;
  StartTable = ARRAY [0 .. 255] OF INTEGER;
  GetCH      = PROCEDURE (INT32): CHAR;
VAR
  lastCh,
  ch:        CHAR;       (*current input character*)
  curLine:   INTEGER;    (*current input line (may be higher than line)*)
  lineStart: INT32;      (*start position of current line*)
  apx:       INT32;      (*length of appendix (CONTEXT phrase)*)
  oldEols:   INTEGER;    (*number of EOLs in a comment*)
  bp, bp0:   INT32;      (*current position in buf
                           (bp0: position of current token)*)
  LBlkSize:  INT32;      (*BlkSize*)
  inputLen:  INT32;      (*source file size*)
  buf:       Buffer;     (*source buffer for low-level access*)
  start:     StartTable; (*start state for every character*)
  CurrentCh: GetCH;

PROCEDURE ORDL (n: INT32): CARDINAL;
 BEGIN
   RETURN FileIO.ORDL(n)
 END ORDL;

PROCEDURE Err (nr, line, col: INTEGER; pos: INT32);
  BEGIN
    INC(errors)
  END Err;

PROCEDURE NextCh;
(* Return global variable ch *)
  BEGIN
    lastCh := ch; INC(bp); ch := CurrentCh(bp);
    IF (ch = EOL) OR (ch = FileIO.LF) AND (lastCh # EOL) THEN
      INC(curLine); lineStart := bp
    END
  END NextCh;

PROCEDURE Comment (): BOOLEAN;
  VAR
    level, startLine: INTEGER;
    oldLineStart: INT32;
  BEGIN
    level := 1; startLine := curLine; oldLineStart := lineStart;
    -->commentRETURN FALSE;
  END Comment;

PROCEDURE Get (VAR sym: CARDINAL);
  VAR
    state: CARDINAL;

  PROCEDURE Equal (s: ARRAY OF CHAR): BOOLEAN;
    VAR
      i: CARDINAL;
      q: INT32;
    BEGIN
      IF nextLen # FileIO.SLENGTH(s) THEN RETURN FALSE END;
      i := 1; q := bp0; INC(q);
      WHILE i < nextLen DO
        IF CurrentCh(q) # s[i] THEN RETURN FALSE END;
        INC(i); INC(q)
      END;
      RETURN TRUE
    END Equal;

  PROCEDURE CheckLiteral;
    BEGIN
      -->literals
    END CheckLiteral;

  BEGIN (*Get*)
    -->GetSy1
    pos := nextPos;   nextPos := bp;
    col := nextCol;   nextCol := FileIO.INTL(bp - lineStart);
    line := nextLine; nextLine := curLine;
    len := nextLen;   nextLen := 0;
    apx := FileIO.Long0; state := start[ORD(ch)]; bp0 := bp;
    LOOP
      NextCh; INC(nextLen);
      CASE state OF
      -->GetSy2
      ELSE sym := noSym; RETURN (*NextCh already done*)
      END
    END
  END Get;

PROCEDURE GetString (pos: INT32; len: CARDINAL; VAR s: ARRAY OF CHAR);
  VAR
    i: CARDINAL;
    p: INT32;
  BEGIN
    IF len > HIGH(s) THEN len := HIGH(s) END;
    p := pos; i := 0;
    WHILE i < len DO
      s[i] := CharAt(p); INC(i); INC(p)
    END;
    s[len] := 0C;
  END GetString;

PROCEDURE GetName (pos: INT32; len: CARDINAL; VAR s: ARRAY OF CHAR);
  VAR
    i: CARDINAL;
    p: INT32;
  BEGIN
    IF len > HIGH(s) THEN len := HIGH(s) END;
    p := pos; i := 0;
    WHILE i < len DO
      s[i] := CurrentCh(p); INC(i); INC(p)
    END;
    s[len] := 0C;
  END GetName;

PROCEDURE CharAt (pos: INT32): CHAR;
  VAR
    ch: CHAR;
  BEGIN
    IF pos >= inputLen THEN RETURN FileIO.EOF END;
    ch := buf^[FileIO.ORDL(pos)];
    IF ch # eof THEN RETURN ch ELSE RETURN FileIO.EOF END
  END CharAt;

PROCEDURE CapChAt (pos: INT32): CHAR;
  VAR
    ch: CHAR;
  BEGIN
    IF pos >= inputLen THEN RETURN FileIO.EOF END;
    ch := CAP(buf^[FileIO.ORDL(pos)]);
    IF ch # eof THEN RETURN ch ELSE RETURN FileIO.EOF END
  END CapChAt;

PROCEDURE Reset;
  VAR
    read: CARDINAL;
  BEGIN (*assert: src has been opened*)
    inputLen := FileIO.Length(src);
    IF inputLen >= LBlkSize THEN
      FileIO.WriteString(FileIO.err,
                         "Input file too long - use another scanner frame file");
      FileIO.QuitExecution;
    END;
    Storage.ALLOCATE(buf, FileIO.ORDL(inputLen) + 1);
    read := FileIO.ORDL(inputLen); FileIO.ReadBytes(src, buf^, read);
    buf^[read] := EOF;
    curLine := 1; lineStart := -FileIO.Long2; bp := -FileIO.Long1;
    oldEols := 0; apx := FileIO.Long0; errors := 0;
    NextCh;
  END Reset;

BEGIN
  -->initializations
  Error := Err; LBlkSize := FileIO.INT(BlkSize); lastCh := EOF;
END -->modulename.
-->definitionDEFINITION MODULE -->modulename;

(* Scanner generated by Coco/R - assuming FileIO library will be available. *)

IMPORT FileIO;

TYPE
  INT32 = FileIO.INT32;

VAR
  src, lst:    FileIO.File;  (*source/list files. To be opened by the main pgm*)
  directory:   ARRAY [0 .. 255] OF CHAR (*of source file*);
  line, col:   INTEGER;      (*line and column of current symbol*)
  len:         CARDINAL;     (*length of current symbol*)
  pos:         INT32;        (*file position of current symbol*)
  nextLine:    INTEGER;      (*line of lookahead symbol*)
  nextCol:     INTEGER;      (*column of lookahead symbol*)
  nextLen:     CARDINAL;     (*length of lookahead symbol*)
  nextPos:     INT32;        (*file position of lookahead symbol*)
  errors:      INTEGER;      (*number of detected errors*)
  Error:       PROCEDURE ((*nr*)INTEGER, (*line*)INTEGER, (*col*)INTEGER,
                          (*pos*)INT32);

PROCEDURE Get (VAR sym: CARDINAL);
(* Gets next symbol from source file *)

PROCEDURE GetString (pos: INT32; len: CARDINAL; VAR name: ARRAY OF CHAR);
(* Retrieves exact string of max length len from position pos in source file *)

PROCEDURE GetName (pos: INT32; len: CARDINAL; VAR name: ARRAY OF CHAR);
(* Retrieves name of symbol of length len at position pos in source file *)

PROCEDURE CharAt (pos: INT32): CHAR;
(* Returns exact character at position pos in source file *)

PROCEDURE Reset;
(* Reads and stores source file internally *)

END -->modulename.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -