HelloWorld 善戰者,求之于勢,不責于人;故能擇人而任勢。

          知止而后有定,定而后能靜,靜而后能安,安而后能慮,慮而后能得。物有本末,事有終始。知所先后,則近道矣。

            BlogJava :: 首頁 ::  :: 聯系 ::  :: 管理 ::
            167 隨筆 :: 1 文章 :: 40 評論 :: 0 Trackbacks
          剛剛學習編譯原理,這是第二章的代碼的改寫,源碼
          http://www.aygfsteel.com/Files/zhaochengming/compiler%20section%202%20parse.rar

          1.KeyWord.java 關鍵字對象類
          package parse;

          public class KeyWord {
              
          private String lexptr;
              
          private int token;
              
          public KeyWord(String lexptr, int token) {
                  
          this.lexptr = lexptr;
                  
          this.token = token;
              }

              
          public String getLexptr() {
                  
          return lexptr;
              }

              
          public void setLexptr(String lexptr) {
                  
          this.lexptr = lexptr;
              }

              
          public int getToken() {
                  
          return token;
              }

              
          public void setToken(int token) {
                  
          this.token = token;
              }

          }

          2.SymTable.java 符號表對象類
          package parse;

          import java.util.ArrayList;
          import java.util.List;

          /**
           * 符號表
           * 
          @author Administrator
           *
           
          */

          public class SymTable {
              
          private static List<KeyWord> SYMTABLE = new ArrayList<KeyWord>();
              
          // 符號表最大容量
              private static final int SYMMAX = 999;
              
          // 字符串最大長度
              public static final int STRMAX = 100;
              
          private static final KeyWord KEYWORDS[] = {
                  
          new KeyWord(null,0),
                  
          new KeyWord("DIV", Token.DIV),
                  
          new KeyWord("ADD", Token.ADD),
                  
          new KeyWord("SUB", Token.SUB),
                  
          new KeyWord("MOD", Token.MOD),
                  
          new KeyWord("MUL", Token.MUL),
              }
          ;
              
              
          // 初始化symtable
              static {
                  
          for(KeyWord keyword : KEYWORDS) {
                      insert(keyword.getLexptr(), keyword.getToken());
                  }

              }

              
              
          /**
               * 在符號表中插入新的符號
               * 
          @param lexptr
               * 
          @param token
               * 
          @return
               
          */

              
          public static int insert(String lexptr, int token) {
                  
          int lexptrlen = 0;
                  
          if(lexptr != null) lexptrlen = lexptr.length();
                  
          if(SYMTABLE.size() >= SYMMAX) {
                      
          throw new IllegalStateException("符號表滿。");
                  }

                  
          if(lexptrlen >= STRMAX) {
                      
          throw new IllegalStateException("lexptr超過最大長度。");
                  }

                  SYMTABLE.add(
          new KeyWord(lexptr, token));
                  
          return SYMTABLE.size() - 1;
              }

              
              
          /**
               * 返回lexptr在符號表中的下標
               * 
          @param lexptr
               * 
          @return
               
          */

              
          public static int lookup(String lexptr) {
                  
          for (int i = 1; i < SYMTABLE.size(); i++{
                      
          if(SYMTABLE.get(i).getLexptr().equals(lexptr)) {
                          
          return i;
                      }

                  }

                  
          return 0;
              }

              
              
          public static KeyWord getKeyWord(int index) {
                  
          return SYMTABLE.get(index);
              }

              
          }


          3.Lex.java 詞法分析對象類
          package parse;


          public class Lex {
              
          private int last = -1;
              
          private int pos = 0;            // 當前位置
              private ParseReader pr;
              
          private String buf;
              
          private int tokenVal;
              
          private Parser parser;
              
              
          public Lex(ParseReader pr, Parser parse) {
                  
          this.pr = pr;
                  
          this.parser = parse;
              }

              
              
          public int lexan() {
                  
          int t;
                  
          while (true{
                      t 
          = getChar();
                      
          if(t == ' ' || t == '\r');
                      
          else if(isDigit(t)) {
                          tokenVal 
          = 0;
                          
          while(isDigit(t)) {
                              tokenVal 
          = tokenVal* 10 + (t - '0');
                              t 
          = getChar();
                          }

                          ungetc(t);
                          
          return Token.NUM;
                      }
           else if (isAlpha(t)) {
                          
          int p = -1, b = 0;
                          StringBuilder sb 
          = new StringBuilder();
                          
          while (isDigit(t) || isAlpha(t)) {
                              sb.append((
          char)t);
                              t 
          = getChar();
                              b
          ++;
                          }

                          
          if(b >= SymTable.STRMAX) {
                              parser.error(
          "詞法分析錯誤");
                          }

                          
          if(t != Token.EOF) {
                              ungetc(t);
                          }

                          p 
          = SymTable.lookup(sb.toString());
                          
          if(p == 0{
                              p 
          = SymTable.insert(sb.toString(), Token.ID);
                          }

                          tokenVal 
          = p;
                          
          return SymTable.getKeyWord(tokenVal).getToken();
                          
                      }
           else if (t == Token.EOF) {
                          
          return Token.DONE;
                      }
           else {
                          tokenVal 
          = Token.NULL;
                          
          return t;
                      }

                  }

              }

              
              
          public int getTokenVal() {
                  
          return tokenVal;
              }

              
              
          public int getChar() {
                  
          if(last < 0{
                      
          if(buf != null && pos < buf.length()) {
                          
          return buf.charAt(pos++);
                      }
           else {
                          
          if(pr.isEof()) {
                              
          return Token.EOF;
                          }
           else {
                              buf 
          = pr.readLine();
                              pos 
          = 0;
                              
          return getChar();
                          }

                      }

                  }
           else {
                      
          int c = last;
                      last 
          = -1;
                      
          return c;
                  }

              }

              
              
          public void ungetc(int c) {
                  last 
          = c;
              }

              
              
          public boolean isDigit(int t) {
                  
          return t >= '0' && t <= '9';
              }
              
              
          public boolean isAlpha (int t) {
                  
          return ((t >= 'A' && t <= 'Z'|| (t >= 'a' && t <= 'z'));
              }
              
              
              
          public int getLineNo() {
                  
          return pr.getLineNo();
              }

              
              
          public int getPos() {
                  
          return pos;
              }

              
              
              
          }


          4.Parser.java 語法分析對象類
          package parse;

          import java.io.FileNotFoundException;

          public class Parser {
              
          private StringBuilder temp = new StringBuilder();
              
          private Lex lex;
              
          int lookahead;

              
          public Parser(ParseReader pr) {
                  lex 
          = new Lex(pr,this);
              }

              
              
          public void parse() {
                  lookahead 
          = lex.lexan();
                  
          while (lookahead != Token.DONE) {
                      expr(); match(
          ';');
                  }

                  out(
          "后綴表達式為: "+temp.toString());
              }

              
              
          private void expr() {
                  
          int t;
                  term();
                  
          while(true{
                      
          switch(lookahead) {
                      
          case '+':
                      
          case '-':
                      
          case Token.ADD:
                      
          case Token.SUB:
                          t 
          = lookahead;
                          match(lookahead); term(); emit(t, Token.NULL);
                          
          continue;
                      
          default:
                          
          return;
                      }

                  }

              }

              
              
          private void term() {
                  
          int t;
                  factor();
                  
          while(true){
                      
          switch(lookahead) {
                      
          case '*':
                      
          case '/':
                      
          case '%':
                      
          case Token.MOD:
                      
          case Token.DIV:
                      
          case Token.MUL:
                          t 
          = lookahead;
                          match(lookahead); factor(); emit(t, Token.NULL);
                          
          continue;
                      
          default:
                          
          return;
                      }

                  }

              }

              
              
          private void factor() {
                  
          switch(lookahead) {
                  
          case '(':
                      match(
          '('); expr(); match(')'); break;
                  
          case Token.NUM:
                      emit(Token.NUM, lex.getTokenVal()); match(Token.NUM); 
          break;
                  
          case Token.ID:
                      emit(Token.ID, lex.getTokenVal()); match(Token.ID); 
          break;
                  
          default:
                      error(
          "語法分析錯誤");
                  }

              }

              
              
          private void match(int t) {
                  
          if(lookahead == t) {
                      lookahead 
          = lex.lexan();
                  }
           else error("語法錯誤");
              }


              
              
          public void emit(int t, int token) {
                  
          switch(t) {
                  
          case '+':
                  
          case '-':
                  
          case '*':
                  
          case '%':
                  
          case '/':
                      temp.append(
          " ").append((char)t).append(" ");
                      out(String.valueOf((
          char)t));break;
                  
          case Token.DIV:
                      temp.append(
          " DIV ");
                      out(
          "DIV");break;
                  
          case Token.MOD:
                      temp.append(
          " MOD ");
                      out(
          "MOD");break;
                  
          case Token.MUL:
                      temp.append(
          " MUL ");
                      out(
          "MUL");break;
                  
          case Token.ADD:
                      temp.append(
          " ADD ");
                      out(
          "ADD");break;
                  
          case Token.SUB:
                      temp.append(
          " SUB ");
                      out(
          " SUB ");break;
                  
          case Token.ID:
                      temp.append(SymTable.getKeyWord(token).getLexptr());
                      out(SymTable.getKeyWord(token).getLexptr());
                      
          break;
                  
          default:
                      temp.append(
          " ").append(token).append(" ");
                      out(
          "token " + Token.name(t) + ", tokenval "+token);
                  }

              }


              
          public void out(String msg) {
                  System.out.println(msg);
              }

              
              
          public static void main(String args[]) {
                  Parser pr;
                  
          try {
                      pr 
          = new Parser(new ParseReaderRAF("c:/a.txt"));
                      pr.parse();
                      
                  }
           catch (FileNotFoundException e) {
                      e.printStackTrace();
                  }

              }

              
              
          public void error(String msg) {
                  System.err.println(
          "ERROR:[" + msg + "] LineNumber : " + lex.getLineNo() +", position :" + lex.getPos());
                  System.exit(
          0);
              }

          }


          5.ParseReader 詞法分析讀字符流接口
          package parse;

          public interface ParseReader {
              
          public String readLine();
              
          public boolean isEof();
              
          public int getLineNo();
          }

          6.ParseReaderRAF 詞法分析讀字符流RandomAccessFile對象
          package parse;

          import java.io.File;
          import java.io.FileNotFoundException;
          import java.io.IOException;
          import java.io.RandomAccessFile;

          public class ParseReaderRAF implements ParseReader{
              
          private RandomAccessFile raf;
              
          private int lineno = 0;
              
          private String buf;
              
          public ParseReaderRAF(String filepath) throws FileNotFoundException {
                  
          this.raf = new RandomAccessFile(new File(filepath), "r");
              }


              
          public int getLineNo() {
                  
          return lineno;
              }


              
          public boolean isEof() {
                  
          try {
                      
          if(raf.getFilePointer() >= raf.length())
                          
          return true;
                  }
           catch (IOException e) {
                      e.printStackTrace();
                  }

                  
          return false;
              }


              
          public String readLine() {
                  
          try {
                      buf 
          = raf.readLine();
                      
          //System.out.println(buf);
                      lineno++;
                  }
           catch (Exception e) {
                      e.printStackTrace();
                  }

                  
          return buf;
              }


          }



          </script>

          posted on 2009-05-15 22:20 helloworld2008 閱讀(613) 評論(0)  編輯  收藏 所屬分類: 編譯原理

          只有注冊用戶登錄后才能發表評論。


          網站導航:
          博客園   IT新聞   Chat2DB   C++博客   博問  
           
          主站蜘蛛池模板: 齐河县| 呼和浩特市| 安陆市| 阆中市| 宁津县| 壶关县| 綦江县| 磐安县| 湖北省| 环江| 长治市| 新野县| 新沂市| 上杭县| 苍南县| 郁南县| 翁源县| 婺源县| 安阳市| 巍山| 永州市| 高雄县| 丁青县| 翁牛特旗| 册亨县| 星座| 尉氏县| 仁布县| 黄骅市| 澎湖县| 红桥区| 古田县| 阳西县| 涞水县| 梁山县| 南城县| 公安县| 庆元县| 滁州市| 霞浦县| 综艺|