Ladies_Man

#COMPLR Lab4 Scanner COMPLETE

Apr 26th, 2016
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.70 KB | None | 0 0
  1. //Объектно-ориентированный лексический анализатор
  2.  
  3. //Compiler, MyScanner, complab4, Position, Fragment, Message, DomainTag, Token, IdentToken, KeyToken
  4.  
  5.  
  6. import java.util.ArrayList;
  7. import java.util.List;
  8.  
  9. public class MyScanner {
  10.     public final String program;
  11.  
  12.     private Compiler compiler;
  13.     private Position cur;
  14.     private List<Fragment> comments;
  15.  
  16.     public void outputComments() {
  17.         System.out.println();
  18.         System.out.println("Comments:");
  19.  
  20.         for (Fragment f : comments) {
  21.             int commStart = f.starting.getIndex();
  22.             int commEnd = f.following.getIndex();
  23.  
  24.             System.out.println(f.toString() + ": " + program.substring(commStart, commEnd).replaceAll("\n", " "));
  25.         }
  26.     }
  27.  
  28.     public MyScanner(String program, Compiler compiler) {
  29.         this.compiler = compiler;
  30.         this.cur = new Position(program);
  31.         this.program = program;
  32.         this.comments = new ArrayList<>();
  33.     }
  34.  
  35.     private boolean isValidIdent(String ident) {
  36.         Position identPos = new Position(ident);
  37.         boolean letter = false, digit = false;
  38.  
  39.         if (identPos.isLetter()) digit = true;  //assume "previous char" was a digit
  40.         if (identPos.isDigit()) letter = true;  //-||- letter
  41.  
  42.         while (identPos.isLetterOrDigit()) {
  43.             if (identPos.isLetter()) {  //letter found
  44.                 if (digit) {            //if "prev char" on current iteration is digit then
  45.                     letter = true;      //"prev char" on next iteration will be a letter
  46.                     digit = false;
  47.  
  48.                     identPos.nxt();
  49.                     continue;
  50.                 }
  51.                 if (letter)
  52.                     return false;
  53.             }
  54.             if (identPos.isDigit()) {
  55.                 if (letter) {
  56.                     letter = false;
  57.                     digit = true;
  58.  
  59.                     identPos.nxt();
  60.                     continue;
  61.                 }
  62.                 if (digit)
  63.                     return false;
  64.             }
  65.         }
  66.         return true;
  67.     }
  68.  
  69.     //Var 2
  70.     //Комментарии: начинаются с «/∗», заканчиваются на «∗/» и могут пересекать границы строк текста.
  71.     //Идентификаторы: последовательности латинских букв и десятичных цифр,
  72.     // в которых буквы и цифры чередуются.
  73.     //Ключевые слова: «for», «if», «m1».
  74.  
  75.     public Token nextToken() {
  76.         while (-1 != cur.getCp()) {
  77.  
  78.             while (cur.isWhiteSpace() || cur.isNewLine())
  79.                 cur.nxt();
  80.  
  81.             Position start = cur.copy();   //avoid referencing object (otherwise changing 'cur' also changes 'start')
  82.  
  83.             switch (cur.getCp()) {
  84.                 case '/':
  85.  
  86.                     cur.nxt();
  87.                     if ('*' != cur.getCp()) {
  88.  
  89.                         Position curCopy = cur.copy();
  90.                         compiler.addMessage(true, curCopy, "unexpected character in comment: '" +
  91.                                 (char)cur.getCp() + "' found, '*' expected");
  92.                     }
  93.  
  94.                     do {
  95.                         do {
  96.                             cur.nxt();
  97.                         } while ('*' != cur.getCp() && -1 != cur.getCp());
  98.                         cur.nxt();
  99.  
  100.                     } while ('/' != cur.getCp() && -1 != cur.getCp());
  101.  
  102.                     if (-1 == cur.getCp())
  103.                         compiler.addMessage(true, cur, "end of program found, '*/' expected");
  104.  
  105.                     cur.nxt();
  106.  
  107.                     Position curCopy = cur.copy();
  108.                     comments.add(new Fragment(start, curCopy));
  109.  
  110.  
  111.                     break;
  112.  
  113.                 default:
  114.                     if (cur.isLetterOrDigit()) {
  115.  
  116.                         String currWord = "";
  117.                         while (cur.isLetterOrDigit()) {
  118.                             currWord += (char)(cur.getCp());
  119.                             cur.nxt();
  120.                             if (currWord.equals("for") || currWord.equals("if") || currWord.equals("m1"))
  121.                                 return new KeyToken(currWord, start, cur);
  122.                         }
  123.  
  124.                         if (isValidIdent(currWord))
  125.                             return new IdentToken(compiler.addName(currWord), currWord, start, cur);
  126.  
  127.                         compiler.addMessage(true, start, "unexpected character in ident");
  128.                     }
  129.                     break;
  130.             }
  131.             cur.nxt();
  132.         }
  133.         return null;
  134.     }
  135. }
Advertisement
Add Comment
Please, Sign In to add comment