一個簡單詞法分析器的實現代碼(java實現)__java

來源:互聯網
上載者:User

http://www.cnblogs.com/xuqiang/archive/2010/09/21/1953501.html

Main.java

/* * 主程式 */ import java.io.*; import lexer.*; public class Main { public static void main(String[] args) throws IOException { Lexer lexer = new Lexer(); while (lexer.getReaderState() == false) { lexer.scan(); } /* 儲存相關資訊 */ lexer.saveTokens(); lexer.saveSymbolsTable(); } }

Lexer.java

package lexer; import java.io.*; import java.util.*; import symbols.*; public class Lexer { public static int line = 1; /* 記錄行號 */ char peek = ' '; /* 下一個讀入字元 */ Hashtable<String, Word> words = new Hashtable<String, Word>(); /* 符號表 */ private Hashtable<Token, String> table = new Hashtable<Token, String>(); /* token序列 */ private List<String> tokens = new LinkedList<String> (); /* 讀取檔案變數 */ BufferedReader reader = null; /* 儲存當前是否讀取到了檔案的結尾 */ private Boolean isEnd = false; /* 是否讀取到檔案的結尾 */ public Boolean getReaderState() { return this.isEnd; } /* 儲存儲存在table中的 */ public void saveSymbolsTable() throws IOException { FileWriter writer = new FileWriter("符號表.txt"); writer.write("[符號] [符號類型資訊]\n"); writer.write("\r\n"); Enumeration<Token> e = table.keys(); while( e.hasMoreElements() ){ Token token = (Token)e.nextElement(); String desc = table.get(token); /* 寫入檔案 */ writer.write(token + "\t\t\t" + desc + "\r\n"); } writer.flush(); } /* 儲存Tokens */ public void saveTokens() throws IOException { FileWriter writer = new FileWriter("Tokens表.txt"); writer.write("[符號] \n"); writer.write("\r\n"); for(int i = 0; i < tokens.size(); ++i) { String tok = (String)tokens.get(i); /* 寫入檔案 */ writer.write(tok + "\r\n"); } writer.flush(); } void reserve(Word w) { words.put(w.lexme, w); } /* * 建構函式中將關鍵字和類型添加到hashtable words中 */ public Lexer() { /* 初始化讀取檔案變數 */ try { reader = new BufferedReader(new FileReader("輸入.txt")); } catch(IOException e) { System.out.print(e); } /* 關鍵字 */ this.reserve(new Word("if", Tag.IF)); this.reserve(new Word("then", Tag.THEN)); this.reserve(new Word("else", Tag.ELSE)); this.reserve(new Word("while", Tag.WHILE)); this.reserve(new Word("do", Tag.DO)); /* 類型 */ this.reserve(Word.True); this.reserve(Word.False); this.reserve(Type.Int); this.reserve(Type.Char); this.reserve(Type.Bool); this.reserve(Type.Float); } public void readch() throws IOException { /* 這裡應該是使用的是 */ peek = (char)reader.read(); if((int)peek == 0xffff){ this.isEnd = true; } // peek = (char)System.in.read(); } public Boolean readch(char ch) throws IOException { readch(); if (this.peek != ch) { return false; } this.peek = ' '; return true; } public Token scan() throws IOException { /* 消除空白 */ for( ; ; readch() ) { if(peek == ' ' || peek == '\t') continue; else if (peek == '\n') line = line + 1; else break; } /* 下面開始分割關鍵字,標識符等資訊 */ switch (peek) { /* 對於 ==, >=, <=, !=的區分使用狀態機器實現 */ case '=' : if (readch('=')) { tokens.add("=="); return Word.eq; } else { tokens.add("="); return new Token('='); } case '>' : if (readch('=')) { tokens.add(">="); return Word.ge; } else { tokens.add(">"); return new Token('>'); } case '<' : if (readch('=')) { tokens.add("<="); return Word.le; } else { tokens.add("<"); return new Token('<'); } case '!' : if (readch('=')) { tokens.add("!="); return Word.ne; } else { tokens.add("!"); return new Token('!'); } } /* 下面是對數位識別,根據文法的規定的話,這裡的 * 數字只要是能夠識別整數就行. */ if(Character.isDigit(peek)) { int value = 0; do { value = 10 * value + Character.digit(peek, 10); readch(); } while (Character.isDigit(peek)); Num n = new Num(value); tokens.add(n.toString()); //table.put(n, "Num"); return n; } /* * 關鍵字或者是標識符的識別 */ if(Character.isLetter(peek)) { StringBuffer sb = new StringBuffer(); /* 首先得到整個的一個分割 */ do { sb.append(peek); readch(); } while (Character.isLetterOrDigit(peek)); /* 判斷是關鍵字還是標識符 */ String s = sb.toString(); Word w = (Word)words.get(s); /* 如果是關鍵字或者是類型的話,w不應該是空的 */ if(w != null) { // table.put(w, "KeyWord or Type"); tokens.add(w.toString()); return w; /* 說明是關鍵字 或者是類型名 */ } /* 否則就是一個標識符id */ w = new Word(s, Tag.ID); tokens.add(w.toString()); table.put(w, "id"); words.put(s, w); return w; } /* peek中的任一字元都被認為是詞法單元返回 */ Token tok = new Token(peek); // table.put(tok, "Token or Seprator"); if ((int)peek != 0xffff ) tokens.add(tok.toString()); peek = ' '; return tok; } }

Num.java

package lexer; public class Num extends Token{ public final int value; public Num(int v) { super(Tag.NUM); this.value = v; } public String toString() { return "" + value; } }

Tag.java

package lexer; public class Tag { public final static int AND = 256, BASIC = 257, BREAK = 258, DO = 259, ELSE = 260, EQ = 261, /* == */ FALSE = 262, GE = 263, ID = 264, IF = 265, INDEX = 266, LE = 267, MINUS = 268, NE = 269, NUM = 270, OR = 271, REAL = 272, TEMP = 273, TRUE = 274, WHILE = 275, /* 後面添加 */ THEN = 276; }

Token.java

package lexer; public class Token { public final int tag; public Token(int t) { this.tag = t; } public String toString() { return "" + (char)tag; } public static void main(String[] args) { Token tok = new Token('a'); System.out.println(tok); } }

Word.java

/* * 類word用於管理保留字,標識符以及像&&這樣的複合單詞元素 。 */ package lexer; public class Word extends Token { public String lexme = ""; public Word (String s, int t) { super(t); this.lexme = s; } public String toString() { return this.lexme; } public static final Word and = new Word("&&", Tag.AND), or = new Word("||", Tag.OR), eq = new Word ("==", Tag.EQ), ne = new Word("!=", Tag.NE), le = new Word("<=", Tag.LE), ge = new Word(">=", Tag.GE), minus = new Word("minus", Tag.MINUS), True = new Word("true", Tag.TRUE), False = new Word("false", Tag.FALSE), temp = new Word("t", Tag.TEMP); }

Type.java

/* * 說明資料類型 */ package symbols; import lexer.*; public class Type extends Word{ public Type(String s, int tag) { super(s, tag); } public static final Type Int = new Type("int", Tag.BASIC), Float = new Type("float", Tag.BASIC), Char = new Type ("char", Tag.BASIC), Bool = new Type("bool", Tag.BASIC); }

 

============

http://freewxy.iteye.com/blog/870016

什麼是詞法。 

 

  所謂詞法,原始碼由字元流組成,字元流中包括關鍵字,變數名,方法名,括弧等等符號,其中變數名要滿足不能包括標點符號,不能以數字開頭的數字與字母的字串這個條件,對於括弧要成對出現等等,這就是詞法;

 

什麼是詞法分析。

 

  詞法分析階段是編譯過程的第一個階段。這個階段的任務是從左至右一個字元一個字元地讀入來源程式,即對構成來源程式的字元流進行掃描然後根據構詞規則識別單詞(也稱單詞符號或符號)。

 

待分析的簡單語言的詞法:

 

 1) 關鍵字

  begin if then while do end

 2) 運算子和界符

  := + - * / < <= > >= <> = ; ( ) #

 3) 其他單詞是標識符(ID)和整形常數(NUM),通過以下正規式定義:

  ID=letter(letter|digit)*

  NUM=digitdigit*

 4) 空格由空白、定位字元和分行符號組成。空格一般用來分隔ID、NUM、運算子、界符和關鍵字,詞法分析階段通常被忽略。

 

 

                        各種單詞符號對應的種別編碼

單詞符號

種別碼

單詞符號

種別碼

begin

1

:

17

if

2

:=

18

then

3

<

20

while

4

<>

21

do

5

<=

22

end

6

>

23

letter(letter|digit)*

10

>=

24

digitdigit*

11

=

25

+

13

;

26

-

14

(

27

*

15

)

28

/

16

#

0

 

 

詞法剖析器的功能:

 

  輸入:所給文法的來源程式字串

  輸出:二元組(syn, token或sum)構成的序列。

  syn為單詞種別碼;

  token為存放的單詞自身字串;

  sum為整形常數。

  例如:對來源程式begin x:=9;if x>0 then x:=2*x+1/3;end# 經詞法分析後輸出如下序列:(1,begin)(10,’x’) (18,:=) (11,9) (26,;) (2,if)……

 

 

 

流程圖:


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.