├── parsing ├── sample.txt ├── bin │ ├── LexFrame.class │ ├── TextLex.class │ ├── ClientGui.class │ ├── Production.class │ ├── TextParse.class │ ├── AnalyseList.class │ └── LineNumberHeaderView.class ├── .classpath ├── .project ├── src │ ├── Production.java │ ├── LineNumberHeaderView.java │ ├── TextParse.java │ ├── ClientGui.java │ ├── AnalyseList.java │ └── TextLex.java ├── .settings │ └── org.eclipse.jdt.core.prefs ├── grammar.txt └── predictldy.txt ├── README.md ├── semantic ├── bin │ ├── Id.class │ ├── Node.class │ ├── Symbol.class │ ├── TextLex.class │ ├── Token.class │ ├── ClientGui.class │ ├── LexFrame.class │ ├── MyScanner.class │ ├── TextParse.class │ ├── AnalyseList.class │ ├── ConstantType.class │ ├── ErrorToken.class │ ├── LProduction.class │ ├── Production.class │ ├── SymbolName.class │ ├── ErrorProduction.class │ ├── GrammarComplier.class │ ├── SemanticAnalyse.class │ └── LineNumberHeaderView.class ├── .settings │ ├── org.eclipse.core.resources.prefs │ └── org.eclipse.jdt.core.prefs ├── sample.txt ├── src │ ├── ErrorToken.java │ ├── ConstantType.java │ ├── Node.java │ ├── Id.java │ ├── SemanticAnalyse.java │ ├── Symbol.java │ ├── SymbolName.java │ ├── ErrorProduction.java │ ├── LineNumberHeaderView.java │ ├── TextParse.java │ ├── Production.java │ ├── Token.java │ ├── ClientGui.java │ ├── AnalyseList.java │ ├── TextLex.java │ └── MyScanner.java ├── .classpath ├── .project ├── grammar.txt └── predictldy.txt └── ldylex ├── bin ├── ldylex.class ├── LexFrame.class ├── TextLex.class └── LineNumberHeaderView.class ├── .classpath ├── .project ├── .settings └── org.eclipse.jdt.core.prefs └── src ├── LineNumberHeaderView.java ├── ldylex.java └── TextLex.java /parsing/sample.txt: -------------------------------------------------------------------------------- 1 | int main(){ 2 | int a; 3 | a=10; 4 | if(a>0){} 5 | else{} 6 | while(a>0){} 7 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 编译原理实验三个 2 | 3 | 1. ldylex 词法分析器 4 | 2. parsing 语法分析器 5 | 3. senmantic 语义分析器 6 | 7 | 不再维护 8 | -------------------------------------------------------------------------------- /semantic/bin/Id.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/semantic/bin/Id.class -------------------------------------------------------------------------------- /ldylex/bin/ldylex.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/ldylex/bin/ldylex.class -------------------------------------------------------------------------------- /semantic/bin/Node.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/semantic/bin/Node.class -------------------------------------------------------------------------------- /ldylex/bin/LexFrame.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/ldylex/bin/LexFrame.class -------------------------------------------------------------------------------- /ldylex/bin/TextLex.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/ldylex/bin/TextLex.class -------------------------------------------------------------------------------- /parsing/bin/LexFrame.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/parsing/bin/LexFrame.class -------------------------------------------------------------------------------- /parsing/bin/TextLex.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/parsing/bin/TextLex.class -------------------------------------------------------------------------------- /semantic/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding/=UTF-8 3 | -------------------------------------------------------------------------------- /semantic/bin/Symbol.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/semantic/bin/Symbol.class -------------------------------------------------------------------------------- /semantic/bin/TextLex.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/semantic/bin/TextLex.class -------------------------------------------------------------------------------- /semantic/bin/Token.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/semantic/bin/Token.class -------------------------------------------------------------------------------- /parsing/bin/ClientGui.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/parsing/bin/ClientGui.class -------------------------------------------------------------------------------- /parsing/bin/Production.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/parsing/bin/Production.class -------------------------------------------------------------------------------- /parsing/bin/TextParse.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/parsing/bin/TextParse.class -------------------------------------------------------------------------------- /semantic/bin/ClientGui.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/semantic/bin/ClientGui.class -------------------------------------------------------------------------------- /semantic/bin/LexFrame.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/semantic/bin/LexFrame.class -------------------------------------------------------------------------------- /semantic/bin/MyScanner.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/semantic/bin/MyScanner.class -------------------------------------------------------------------------------- /semantic/bin/TextParse.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/semantic/bin/TextParse.class -------------------------------------------------------------------------------- /parsing/bin/AnalyseList.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/parsing/bin/AnalyseList.class -------------------------------------------------------------------------------- /semantic/bin/AnalyseList.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/semantic/bin/AnalyseList.class -------------------------------------------------------------------------------- /semantic/bin/ConstantType.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/semantic/bin/ConstantType.class -------------------------------------------------------------------------------- /semantic/bin/ErrorToken.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/semantic/bin/ErrorToken.class -------------------------------------------------------------------------------- /semantic/bin/LProduction.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/semantic/bin/LProduction.class -------------------------------------------------------------------------------- /semantic/bin/Production.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/semantic/bin/Production.class -------------------------------------------------------------------------------- /semantic/bin/SymbolName.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/semantic/bin/SymbolName.class -------------------------------------------------------------------------------- /semantic/bin/ErrorProduction.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/semantic/bin/ErrorProduction.class -------------------------------------------------------------------------------- /semantic/bin/GrammarComplier.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/semantic/bin/GrammarComplier.class -------------------------------------------------------------------------------- /semantic/bin/SemanticAnalyse.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/semantic/bin/SemanticAnalyse.class -------------------------------------------------------------------------------- /ldylex/bin/LineNumberHeaderView.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/ldylex/bin/LineNumberHeaderView.class -------------------------------------------------------------------------------- /parsing/bin/LineNumberHeaderView.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/parsing/bin/LineNumberHeaderView.class -------------------------------------------------------------------------------- /semantic/bin/LineNumberHeaderView.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luciferldy/Compiler_Experiment/HEAD/semantic/bin/LineNumberHeaderView.class -------------------------------------------------------------------------------- /semantic/sample.txt: -------------------------------------------------------------------------------- 1 | int main(){ 2 | int a; 3 | a=10; 4 | if(a>0){ 5 | a=1; 6 | } 7 | else{ 8 | a=2; 9 | } 10 | while(a>0){ 11 | a=3; 12 | } 13 | } -------------------------------------------------------------------------------- /semantic/src/ErrorToken.java: -------------------------------------------------------------------------------- 1 | public class ErrorToken extends Token { 2 | 3 | public ErrorToken(String name,String source){ 4 | super(name,source); 5 | } 6 | 7 | public ErrorToken(String name,String value,String source){ 8 | super(name,source); 9 | this.value=value; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ldylex/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /parsing/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /semantic/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ldylex/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ldylex 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /parsing/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | parsing 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /semantic/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | semantic 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /semantic/src/ConstantType.java: -------------------------------------------------------------------------------- 1 | public class ConstantType { 2 | public static String INT="int"; 3 | public static String UNSIGNED="unsigned"; 4 | public static String LONG="long"; 5 | public static String LONG_UNSIGNED="long_unsigned"; 6 | public static String FLOAT="float"; 7 | public static String DOUBLE="double"; 8 | public static String LONG_DOUBLE="long_double"; 9 | public static String CHAR="char"; 10 | public static String STRING="string"; 11 | } 12 | -------------------------------------------------------------------------------- /parsing/src/Production.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | 4 | // 产生式类 5 | public class Production{ 6 | String left; 7 | String[] right; 8 | // 初始化select集 9 | ArrayList select = new ArrayList(); 10 | public Production(String left, String[] right){ 11 | this.left = left; 12 | this.right = right; 13 | } 14 | 15 | public String[] returnRights(){ 16 | return right; 17 | } 18 | 19 | public String returnLeft(){ 20 | return left; 21 | } 22 | 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ldylex/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.7 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.7 12 | -------------------------------------------------------------------------------- /parsing/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.7 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.7 12 | -------------------------------------------------------------------------------- /semantic/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.7 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.7 12 | -------------------------------------------------------------------------------- /semantic/src/Node.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.HashMap; 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | public class Node { 7 | String symbol_name; 8 | Node father; 9 | public List sons; 10 | public Map attribute; 11 | 12 | public Node(String symbolName, Node father) { 13 | super(); 14 | symbol_name = symbolName; 15 | this.father = father; 16 | sons=new ArrayList(); 17 | attribute=new HashMap(); 18 | } 19 | 20 | public void setSons(List sons) { 21 | this.sons = sons; 22 | } 23 | 24 | public String getSymbol_name() { 25 | return symbol_name; 26 | } 27 | 28 | public Node getFather() { 29 | return father; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /semantic/src/Id.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | public class Id { 5 | String name; 6 | String type;//基本类型 7 | int offset;//起始地址 8 | int length;//长度 9 | public List arr_list;//各维下标 10 | 11 | public Id(String name, String type, int offset, int length) { 12 | super(); 13 | this.name = name; 14 | this.type = type; 15 | this.offset = offset; 16 | this.length = length; 17 | 18 | arr_list=new ArrayList(); 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public String getType() { 26 | return type; 27 | } 28 | 29 | public int getOffset() { 30 | return offset; 31 | } 32 | 33 | public int getLength() { 34 | return length; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /semantic/src/SemanticAnalyse.java: -------------------------------------------------------------------------------- 1 | import java.util.List; 2 | 3 | import javax.swing.table.DefaultTableModel; 4 | 5 | public class SemanticAnalyse{ 6 | DefaultTableModel tbmodel_symbol_list; 7 | DefaultTableModel tbmodel_triples; 8 | String text_input; 9 | 10 | public SemanticAnalyse(String text_input, DefaultTableModel tbmodel_symbol_list, DefaultTableModel tbmodel_triples){ 11 | this.text_input = text_input; 12 | this.tbmodel_triples = tbmodel_triples; 13 | this.tbmodel_symbol_list = tbmodel_symbol_list; 14 | } 15 | 16 | public void Parsing(){ 17 | MyScanner scan=new MyScanner(text_input); 18 | List token_list=scan.execute(); 19 | GrammarComplier gc=new GrammarComplier(); 20 | gc.analysis(token_list); 21 | List codes=gc.getCodes(); 22 | List ids=gc.getIds(); 23 | String output[] = new String[5]; 24 | 25 | codes.add("END"); 26 | for(int i = 0; i < ids.size(); i++){ 27 | output[0] = "<" + (i+1) + ">"; 28 | output[1] = ids.get(i).getName(); 29 | String type = ids.get(i).getType(); 30 | for(int m = 0; m < ids.get(i).arr_list.size(); m++){ 31 | type = type + "[" + ids.get(i).arr_list.get(m) + "]"; 32 | } 33 | output[2] = type; 34 | output[3] = ids.get(i).getOffset() + ""; 35 | output[4] = ids.get(i).getLength() + ""; 36 | // 输出符号表 37 | tbmodel_symbol_list.addRow(new String[]{output[1], output[2], output[4], output[3]}); 38 | } 39 | for(int n = 0; n < codes.size(); n++){ 40 | // 输出三地址指令 41 | tbmodel_triples.addRow(new String[]{n+"", codes.get(n)}); 42 | } 43 | } 44 | 45 | 46 | } -------------------------------------------------------------------------------- /semantic/src/Symbol.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | //import java.util.HashMap; 3 | import java.util.List; 4 | //import java.util.Map; 5 | 6 | public class Symbol { 7 | int no; 8 | private String name; 9 | private char type;//N代表非终结符,T代表终结符 10 | private String higher_name;//高层结构的符号 11 | public List first; 12 | public List follow; 13 | // public Map attribute; 14 | // public List select; 产生式才有可选集 15 | 16 | public Symbol(int no, String name, char type) { 17 | super(); 18 | this.no=no; 19 | this.name = name; 20 | this.type=type; 21 | this.first = new ArrayList(); 22 | // this.attribute=new HashMap(); 23 | 24 | if(type=='N'){ 25 | this.follow = new ArrayList(); 26 | // this.select = new ArrayList(); 27 | }else if(type=='T'){ 28 | this.first.add(name);//非终结符的first集只包含它自身 29 | this.follow = null; 30 | // this.select = null; 31 | }else{ 32 | throw new IllegalArgumentException("非法的符号类型"); 33 | } 34 | } 35 | 36 | public Symbol(int no, String name, char type, String higher_name){ 37 | this(no, name, type); 38 | this.higher_name=higher_name; 39 | } 40 | 41 | public String getName() { 42 | return name; 43 | } 44 | 45 | public String getHigher_name() { 46 | return higher_name; 47 | } 48 | 49 | public boolean isTerminal(){ 50 | if(type=='N') 51 | return false; 52 | else 53 | return true; 54 | } 55 | 56 | public boolean has(String arr_name, String sym_name){ 57 | List arr=null; 58 | 59 | if(arr_name.toUpperCase().equals("FIRST")) 60 | arr=this.first; 61 | else if(arr_name.toUpperCase().equals("FOLLOW")) 62 | arr=this.follow; 63 | // else if(arr_name.toUpperCase().equals("SELECT")) 64 | // arr=this.select; 65 | else 66 | throw new IllegalArgumentException("非法的集合名"); 67 | 68 | for(int i=0;i func funcs 2 | funcs -> func funcs 3 | funcs -> $ 4 | func -> type IDN ( args ) func_body 5 | type -> int 6 | type -> short 7 | type -> long 8 | type -> char 9 | type -> float 10 | type -> double 11 | type -> void 12 | type -> unsigned type 13 | args -> type IDN arg 14 | args -> $ 15 | arg -> , type IDN arg 16 | arg -> $ 17 | func_body -> ; 18 | func_body -> block 19 | block -> { define_stmts stmts } 20 | define_stmts -> define_stmt define_stmts 21 | define_stmts -> $ 22 | define_stmt -> type IDN init vars ; 23 | init -> = expression 24 | init -> $ 25 | vars -> , IDN init vars 26 | vars -> $ 27 | stmts -> stmt stmts 28 | stmts -> $ 29 | stmt -> assign_stmt 30 | stmt -> jump_stmt 31 | stmt -> iteration_stmt 32 | stmt -> branch_stmt 33 | assign_stmt -> expression ; 34 | jump_stmt -> continue ; 35 | jump_stmt -> break ; 36 | jump_stmt -> return isnull_expr ; 37 | iteration_stmt -> while ( logical_expression ) block_stmt 38 | iteration_stmt -> for ( isnull_expr ; isnull_expr ; isnull_expr ) block_stmt 39 | iteration_stmt -> do block_stmt while ( logical_expression ) ; 40 | branch_stmt -> if ( logical_expression ) block_stmt result 41 | result -> else block_stmt 42 | result -> $ 43 | logical_expression -> ! expression bool_expression 44 | logical_expression -> expression bool_expression 45 | bool_expression -> lop expression bool_expression 46 | bool_expression -> $ 47 | lop -> && 48 | lop -> || 49 | branch_stmt -> switch ( IDN ) { case_stmt case_stmts default_stmt } 50 | case_stmts -> case_stmt case_stmts 51 | case_stmts -> $ 52 | case_stmt -> case const : stmts 53 | default_stmt -> default : stmts 54 | block_stmt -> { stmts } 55 | isnull_expr -> expression 56 | isnull_expr -> $ 57 | expression -> value operation 58 | operation -> compare_op value 59 | operation -> equal_op value 60 | operation -> $ 61 | compare_op -> > 62 | compare_op -> >= 63 | compare_op -> < 64 | compare_op -> <= 65 | compare_op -> == 66 | compare_op -> != 67 | equal_op -> = 68 | equal_op -> += 69 | equal_op -> -= 70 | equal_op -> *= 71 | equal_op -> /= 72 | equal_op -> %= 73 | value -> item value' 74 | value' -> + item value' 75 | value' -> - item value' 76 | value' -> $ 77 | item -> factor item' 78 | item' -> * factor item' 79 | item' -> / factor item' 80 | item' -> % factor item' 81 | item' -> $ 82 | factor -> ( value ) 83 | factor -> IDN call_func 84 | factor -> const 85 | call_func -> ( es ) 86 | call_func -> $ 87 | es -> isnull_expr isnull_es 88 | isnull_es -> , isnull_expr isnull_es 89 | isnull_es -> $ 90 | const -> num_const 91 | const -> FLOAT 92 | const -> CHAR 93 | const -> STR 94 | num_const -> INT10 95 | num_const -> INT8 96 | num_const -> INT16 -------------------------------------------------------------------------------- /semantic/grammar.txt: -------------------------------------------------------------------------------- 1 | S -> func funcs 2 | funcs -> func funcs 3 | funcs -> $ 4 | func -> type IDN ( args ) func_body 5 | type -> int 6 | type -> short 7 | type -> long 8 | type -> char 9 | type -> float 10 | type -> double 11 | type -> void 12 | type -> unsigned type 13 | args -> type IDN arg 14 | args -> $ 15 | arg -> , type IDN arg 16 | arg -> $ 17 | func_body -> ; 18 | func_body -> block 19 | block -> { define_stmts stmts } 20 | define_stmts -> define_stmt define_stmts 21 | define_stmts -> $ 22 | define_stmt -> type IDN init vars ; 23 | init -> = expression 24 | init -> $ 25 | vars -> , IDN init vars 26 | vars -> $ 27 | stmts -> stmt stmts 28 | stmts -> $ 29 | stmt -> assign_stmt 30 | stmt -> jump_stmt 31 | stmt -> iteration_stmt 32 | stmt -> branch_stmt 33 | assign_stmt -> expression ; 34 | jump_stmt -> continue ; 35 | jump_stmt -> break ; 36 | jump_stmt -> return isnull_expr ; 37 | iteration_stmt -> while ( logical_expression ) block_stmt 38 | iteration_stmt -> for ( isnull_expr ; isnull_expr ; isnull_expr ) block_stmt 39 | iteration_stmt -> do block_stmt while ( logical_expression ) ; 40 | branch_stmt -> if ( logical_expression ) block_stmt result 41 | result -> else block_stmt 42 | result -> $ 43 | logical_expression -> ! expression bool_expression 44 | logical_expression -> expression bool_expression 45 | bool_expression -> lop expression bool_expression 46 | bool_expression -> $ 47 | lop -> && 48 | lop -> || 49 | branch_stmt -> switch ( IDN ) { case_stmt case_stmts default_stmt } 50 | case_stmts -> case_stmt case_stmts 51 | case_stmts -> $ 52 | case_stmt -> case const : stmts 53 | default_stmt -> default : stmts 54 | block_stmt -> { stmts } 55 | isnull_expr -> expression 56 | isnull_expr -> $ 57 | expression -> value operation 58 | operation -> compare_op value 59 | operation -> equal_op value 60 | operation -> $ 61 | compare_op -> > 62 | compare_op -> >= 63 | compare_op -> < 64 | compare_op -> <= 65 | compare_op -> == 66 | compare_op -> != 67 | equal_op -> = 68 | equal_op -> += 69 | equal_op -> -= 70 | equal_op -> *= 71 | equal_op -> /= 72 | equal_op -> %= 73 | value -> item value' 74 | value' -> + item value' 75 | value' -> - item value' 76 | value' -> $ 77 | item -> factor item' 78 | item' -> * factor item' 79 | item' -> / factor item' 80 | item' -> % factor item' 81 | item' -> $ 82 | factor -> ( value ) 83 | factor -> IDN call_func 84 | factor -> const 85 | call_func -> ( es ) 86 | call_func -> $ 87 | es -> isnull_expr isnull_es 88 | isnull_es -> , isnull_expr isnull_es 89 | isnull_es -> $ 90 | const -> num_const 91 | const -> FLOAT 92 | const -> CHAR 93 | const -> STR 94 | num_const -> INT10 95 | num_const -> INT8 96 | num_const -> INT16 -------------------------------------------------------------------------------- /semantic/src/ErrorProduction.java: -------------------------------------------------------------------------------- 1 | public class ErrorProduction extends Production{ 2 | 3 | String error;//错误描述 4 | String solution;//处理描述 5 | 6 | 7 | 8 | // @Override 9 | // public String toString() { 10 | // // TODO Auto-generated method stub 11 | // return "error: "+error+"\nsolution: "+solution; 12 | // } 13 | 14 | public String getError() { 15 | return error; 16 | } 17 | 18 | public void setError(String error) { 19 | this.error = error; 20 | } 21 | 22 | public String getSolution() { 23 | return solution; 24 | } 25 | 26 | public void setSolution(String solution) { 27 | this.solution = solution; 28 | } 29 | 30 | public ErrorProduction(Production father){ 31 | this.no=father.no; 32 | this.left=father.left; 33 | this.right=father.right; 34 | } 35 | 36 | public ErrorProduction(int no, String left, String symbol1, String symbol2, 37 | String symbol3, String symbol4, String symbol5, String symbol6, 38 | String symbol7, String symbol8, String symbol9) { 39 | super(no, left, symbol1, symbol2, symbol3, symbol4, symbol5, symbol6, symbol7, 40 | symbol8, symbol9); 41 | } 42 | 43 | public ErrorProduction(int no, String left, String symbol1, String symbol2, 44 | String symbol3, String symbol4, String symbol5, String symbol6, 45 | String symbol7, String symbol8) { 46 | super(no, left, symbol1, symbol2, symbol3, symbol4, symbol5, symbol6, symbol7, 47 | symbol8); 48 | } 49 | 50 | public ErrorProduction(int no, String left, String symbol1, String symbol2, 51 | String symbol3, String symbol4, String symbol5, String symbol6, 52 | String symbol7) { 53 | super(no, left, symbol1, symbol2, symbol3, symbol4, symbol5, symbol6, symbol7); 54 | } 55 | 56 | public ErrorProduction(int no, String left, String symbol1, String symbol2, 57 | String symbol3, String symbol4, String symbol5, String symbol6) { 58 | super(no, left, symbol1, symbol2, symbol3, symbol4, symbol5, symbol6); 59 | } 60 | 61 | public ErrorProduction(int no, String left, String symbol1, String symbol2, 62 | String symbol3, String symbol4, String symbol5) { 63 | super(no, left, symbol1, symbol2, symbol3, symbol4, symbol5); 64 | } 65 | 66 | public ErrorProduction(int no, String left, String symbol1, String symbol2, 67 | String symbol3, String symbol4) { 68 | super(no, left, symbol1, symbol2, symbol3, symbol4); 69 | } 70 | 71 | public ErrorProduction(int no, String left, String symbol1, String symbol2, 72 | String symbol3) { 73 | super(no, left, symbol1, symbol2, symbol3); 74 | } 75 | 76 | public ErrorProduction(int no, String left, String symbol1, String symbol2) { 77 | super(no, left, symbol1, symbol2); 78 | } 79 | 80 | public ErrorProduction(int no, String left, String symbol1) { 81 | super(no, left, symbol1); 82 | } 83 | 84 | public ErrorProduction(int no, String left) { 85 | super(no, left); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /ldylex/src/LineNumberHeaderView.java: -------------------------------------------------------------------------------- 1 | import java.awt.Color; 2 | import java.awt.Dimension; 3 | import java.awt.Font; 4 | import java.awt.FontMetrics; 5 | import java.awt.Graphics; 6 | import java.awt.Rectangle; 7 | 8 | public class LineNumberHeaderView extends javax.swing.JComponent { 9 | 10 | /** 11 | * 12 | */ 13 | private static final long serialVersionUID = 1L; 14 | private final Font DEFAULT_FONT = new Font(Font.MONOSPACED, Font.PLAIN, 11); 15 | public final Color DEFAULT_BACKGROUD = new Color(228, 228, 228); 16 | public final Color DEFAULT_FOREGROUD = Color.BLACK; 17 | public final int nHEIGHT = Integer.MAX_VALUE - 1000000; 18 | public final int MARGIN = 5; 19 | private int lineHeight; 20 | private int fontLineHeight; 21 | private int currentRowWidth; 22 | private FontMetrics fontMetrics; 23 | 24 | public LineNumberHeaderView() { 25 | setFont(DEFAULT_FONT); 26 | setForeground(DEFAULT_FOREGROUD); 27 | setBackground(DEFAULT_BACKGROUD); 28 | setPreferredSize(9999); 29 | } 30 | 31 | public void setPreferredSize(int row) { 32 | int width = fontMetrics.stringWidth(String.valueOf(row)); 33 | if (currentRowWidth < width) { 34 | currentRowWidth = width; 35 | setPreferredSize(new Dimension(2 * MARGIN + width + 1, nHEIGHT)); 36 | } 37 | } 38 | 39 | @Override 40 | public void setFont(Font font) { 41 | super.setFont(font); 42 | fontMetrics = getFontMetrics(getFont()); 43 | fontLineHeight = fontMetrics.getHeight(); 44 | } 45 | 46 | public int getLineHeight() { 47 | if (lineHeight == 0) { 48 | return fontLineHeight; 49 | } 50 | return lineHeight; 51 | } 52 | 53 | public void setLineHeight(int lineHeight) { 54 | if (lineHeight > 0) { 55 | this.lineHeight = lineHeight; 56 | } 57 | } 58 | 59 | public int getStartOffset() { 60 | return 4; 61 | } 62 | 63 | @Override 64 | protected void paintComponent(Graphics g) { 65 | int nlineHeight = getLineHeight(); 66 | int startOffset = getStartOffset(); 67 | Rectangle drawHere = g.getClipBounds(); 68 | g.setColor(getBackground()); 69 | g.fillRect(drawHere.x, drawHere.y, drawHere.width, drawHere.height); 70 | g.setColor(getForeground()); 71 | int startLineNum = (drawHere.y / nlineHeight) + 1; 72 | int endLineNum = startLineNum + (drawHere.height / nlineHeight); 73 | int start = (drawHere.y / nlineHeight) * nlineHeight + nlineHeight - startOffset; 74 | for (int i = startLineNum; i <= endLineNum; ++i) { 75 | String lineNum = String.valueOf(i); 76 | int width = fontMetrics.stringWidth(lineNum); 77 | g.drawString(lineNum + " ", MARGIN + currentRowWidth - width - 1, start); 78 | start += nlineHeight; 79 | } 80 | setPreferredSize(endLineNum); 81 | } 82 | } -------------------------------------------------------------------------------- /parsing/src/LineNumberHeaderView.java: -------------------------------------------------------------------------------- 1 | import java.awt.Color; 2 | import java.awt.Dimension; 3 | import java.awt.Font; 4 | import java.awt.FontMetrics; 5 | import java.awt.Graphics; 6 | import java.awt.Rectangle; 7 | 8 | public class LineNumberHeaderView extends javax.swing.JComponent { 9 | 10 | /** 11 | * 12 | */ 13 | private static final long serialVersionUID = 1L; 14 | private final Font DEFAULT_FONT = new Font(Font.MONOSPACED, Font.PLAIN, 11); 15 | public final Color DEFAULT_BACKGROUD = new Color(228, 228, 228); 16 | public final Color DEFAULT_FOREGROUD = Color.BLACK; 17 | public final int nHEIGHT = Integer.MAX_VALUE - 1000000; 18 | public final int MARGIN = 5; 19 | private int lineHeight; 20 | private int fontLineHeight; 21 | private int currentRowWidth; 22 | private FontMetrics fontMetrics; 23 | 24 | public LineNumberHeaderView() { 25 | setFont(DEFAULT_FONT); 26 | setForeground(DEFAULT_FOREGROUD); 27 | setBackground(DEFAULT_BACKGROUD); 28 | setPreferredSize(9999); 29 | } 30 | 31 | public void setPreferredSize(int row) { 32 | int width = fontMetrics.stringWidth(String.valueOf(row)); 33 | if (currentRowWidth < width) { 34 | currentRowWidth = width; 35 | setPreferredSize(new Dimension(2 * MARGIN + width + 1, nHEIGHT)); 36 | } 37 | } 38 | 39 | @Override 40 | public void setFont(Font font) { 41 | super.setFont(font); 42 | fontMetrics = getFontMetrics(getFont()); 43 | fontLineHeight = fontMetrics.getHeight(); 44 | } 45 | 46 | public int getLineHeight() { 47 | if (lineHeight == 0) { 48 | return fontLineHeight; 49 | } 50 | return lineHeight; 51 | } 52 | 53 | public void setLineHeight(int lineHeight) { 54 | if (lineHeight > 0) { 55 | this.lineHeight = lineHeight; 56 | } 57 | } 58 | 59 | public int getStartOffset() { 60 | return 4; 61 | } 62 | 63 | @Override 64 | protected void paintComponent(Graphics g) { 65 | int nlineHeight = getLineHeight(); 66 | int startOffset = getStartOffset(); 67 | Rectangle drawHere = g.getClipBounds(); 68 | g.setColor(getBackground()); 69 | g.fillRect(drawHere.x, drawHere.y, drawHere.width, drawHere.height); 70 | g.setColor(getForeground()); 71 | int startLineNum = (drawHere.y / nlineHeight) + 1; 72 | int endLineNum = startLineNum + (drawHere.height / nlineHeight); 73 | int start = (drawHere.y / nlineHeight) * nlineHeight + nlineHeight - startOffset; 74 | for (int i = startLineNum; i <= endLineNum; ++i) { 75 | String lineNum = String.valueOf(i); 76 | int width = fontMetrics.stringWidth(lineNum); 77 | g.drawString(lineNum + " ", MARGIN + currentRowWidth - width - 1, start); 78 | start += nlineHeight; 79 | } 80 | setPreferredSize(endLineNum); 81 | } 82 | } -------------------------------------------------------------------------------- /semantic/src/LineNumberHeaderView.java: -------------------------------------------------------------------------------- 1 | import java.awt.Color; 2 | import java.awt.Dimension; 3 | import java.awt.Font; 4 | import java.awt.FontMetrics; 5 | import java.awt.Graphics; 6 | import java.awt.Rectangle; 7 | 8 | public class LineNumberHeaderView extends javax.swing.JComponent { 9 | 10 | /** 11 | * 12 | */ 13 | private static final long serialVersionUID = 1L; 14 | private final Font DEFAULT_FONT = new Font(Font.MONOSPACED, Font.PLAIN, 11); 15 | public final Color DEFAULT_BACKGROUD = new Color(228, 228, 228); 16 | public final Color DEFAULT_FOREGROUD = Color.BLACK; 17 | public final int nHEIGHT = Integer.MAX_VALUE - 1000000; 18 | public final int MARGIN = 5; 19 | private int lineHeight; 20 | private int fontLineHeight; 21 | private int currentRowWidth; 22 | private FontMetrics fontMetrics; 23 | 24 | public LineNumberHeaderView() { 25 | setFont(DEFAULT_FONT); 26 | setForeground(DEFAULT_FOREGROUD); 27 | setBackground(DEFAULT_BACKGROUD); 28 | setPreferredSize(9999); 29 | } 30 | 31 | public void setPreferredSize(int row) { 32 | int width = fontMetrics.stringWidth(String.valueOf(row)); 33 | if (currentRowWidth < width) { 34 | currentRowWidth = width; 35 | setPreferredSize(new Dimension(2 * MARGIN + width + 1, nHEIGHT)); 36 | } 37 | } 38 | 39 | @Override 40 | public void setFont(Font font) { 41 | super.setFont(font); 42 | fontMetrics = getFontMetrics(getFont()); 43 | fontLineHeight = fontMetrics.getHeight(); 44 | } 45 | 46 | public int getLineHeight() { 47 | if (lineHeight == 0) { 48 | return fontLineHeight; 49 | } 50 | return lineHeight; 51 | } 52 | 53 | public void setLineHeight(int lineHeight) { 54 | if (lineHeight > 0) { 55 | this.lineHeight = lineHeight; 56 | } 57 | } 58 | 59 | public int getStartOffset() { 60 | return 4; 61 | } 62 | 63 | @Override 64 | protected void paintComponent(Graphics g) { 65 | int nlineHeight = getLineHeight(); 66 | int startOffset = getStartOffset(); 67 | Rectangle drawHere = g.getClipBounds(); 68 | g.setColor(getBackground()); 69 | g.fillRect(drawHere.x, drawHere.y, drawHere.width, drawHere.height); 70 | g.setColor(getForeground()); 71 | int startLineNum = (drawHere.y / nlineHeight) + 1; 72 | int endLineNum = startLineNum + (drawHere.height / nlineHeight); 73 | int start = (drawHere.y / nlineHeight) * nlineHeight + nlineHeight - startOffset; 74 | for (int i = startLineNum; i <= endLineNum; ++i) { 75 | String lineNum = String.valueOf(i); 76 | int width = fontMetrics.stringWidth(lineNum); 77 | g.drawString(lineNum + " ", MARGIN + currentRowWidth - width - 1, start); 78 | start += nlineHeight; 79 | } 80 | setPreferredSize(endLineNum); 81 | } 82 | } -------------------------------------------------------------------------------- /semantic/src/TextParse.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.RandomAccessFile; 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | 6 | import javax.swing.table.DefaultTableModel; 7 | 8 | 9 | public class TextParse{ 10 | HashMap predictmap; 11 | ArrayList input_cache; 12 | ArrayList deduce_str; 13 | DefaultTableModel tbmodel_lex_result; 14 | 15 | public TextParse(ArrayList input_cache, DefaultTableModel tbmodel_lex_result){ 16 | predictmap = new HashMap(); 17 | this.input_cache = input_cache; 18 | deduce_str = new ArrayList(); 19 | this.tbmodel_lex_result = tbmodel_lex_result; 20 | getPredictMap(); 21 | } 22 | 23 | // 句法分析 24 | public void Parsing(){ 25 | // 初始符号压入栈 26 | deduce_str.add("S"); 27 | String right; 28 | String leftandinput; 29 | String process=""; 30 | 31 | while (deduce_str.size()>0 && input_cache.size()>0 ) { 32 | 33 | // 输入缓冲区与推导符号串第一个字符相等的话,删掉 34 | try { 35 | if(input_cache.get(0).equals(deduce_str.get(deduce_str.size()-1))){ 36 | input_cache.remove(0); 37 | deduce_str.remove(deduce_str.size()-1); 38 | continue; 39 | } 40 | } catch (Exception e) { 41 | // TODO: handle exception 42 | e.printStackTrace(); 43 | } 44 | 45 | 46 | // 匹配字符 47 | leftandinput = deduce_str.get(deduce_str.size()-1)+"-"+input_cache.get(0); 48 | // if(input_cache.get(0)==null) 49 | // { 50 | // leftandinput = leftandinput+"$"; 51 | // } 52 | // 能够找到匹配的 53 | if((right=predictmap.get(leftandinput))!=null){ 54 | 55 | // 输出产生式和推导过程 56 | process = ""; 57 | for (int i=deduce_str.size()-1;i>-1;i--) { 58 | process = process+deduce_str.get(i)+" "; 59 | } 60 | tbmodel_lex_result.addRow(new String[]{process, deduce_str.get(deduce_str.size()-1)+" -> "+right}); 61 | 62 | // 删掉产生的字符,压入堆栈 63 | deduce_str.remove(deduce_str.size()-1); 64 | if(right.equals("$")){ 65 | // 只弹不压 66 | } 67 | else { 68 | String[] arg = right.split(" "); 69 | for(int i=arg.length-1;i>-1;i--){ 70 | // 反向压入堆栈 71 | deduce_str.add(arg[i]); 72 | } 73 | } 74 | 75 | } 76 | // 否则的话报错 77 | else { 78 | // 重新书写process 79 | process=""; 80 | for (int i=deduce_str.size()-1;i>-1;i--) { 81 | process = process+deduce_str.get(i)+" "; 82 | } 83 | tbmodel_lex_result.addRow(new String[]{process, "ERROR! 无法识别的字符"+input_cache.get(0)+"产生式"+leftandinput}); 84 | input_cache.remove(0); 85 | } 86 | } 87 | } 88 | 89 | // 获得预测分析表中的产生式以及对应的select集 90 | // 存储方式为键值对的形式 91 | public void getPredictMap(){ 92 | String text_line; 93 | String left; 94 | String symbol; 95 | String right; 96 | try { 97 | // 初始化 98 | predictmap = new HashMap(); 99 | // 采用随机读取方式 100 | File file = new File("predictldy.txt"); 101 | RandomAccessFile predictfile = new RandomAccessFile(file,"r"); 102 | while ((text_line = predictfile.readLine())!=null){ 103 | left = text_line.split("#")[0]; 104 | symbol = (text_line.split("#")[1]).split("->")[0].trim(); 105 | right = (text_line.split("#")[1]).split("->")[1].trim(); 106 | predictmap.put(left+"-"+symbol, right); 107 | 108 | } 109 | predictfile.close(); 110 | 111 | } catch (Exception e) { 112 | // TODO: handle exception 113 | e.printStackTrace(); 114 | } 115 | 116 | } 117 | 118 | } -------------------------------------------------------------------------------- /parsing/src/TextParse.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.RandomAccessFile; 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | 6 | import javax.swing.table.DefaultTableModel; 7 | 8 | 9 | public class TextParse{ 10 | HashMap predictmap; 11 | ArrayList input_cache; 12 | ArrayList deduce_str; 13 | DefaultTableModel tbmodel_lex_result; 14 | 15 | public TextParse(ArrayList input_cache, DefaultTableModel tbmodel_lex_result){ 16 | predictmap = new HashMap(); 17 | this.input_cache = input_cache; 18 | deduce_str = new ArrayList(); 19 | this.tbmodel_lex_result = tbmodel_lex_result; 20 | getPredictMap(); 21 | } 22 | 23 | // 句法分析 24 | public void Parsing(){ 25 | // 初始符号压入栈 26 | deduce_str.add("S"); 27 | String right; 28 | String leftandinput; 29 | String process=""; 30 | 31 | while (deduce_str.size()>0 && input_cache.size()>0 ) { 32 | 33 | 34 | // 输入缓冲区与推导符号串第一个字符相等的话,删掉 35 | try { 36 | if(input_cache.get(0).equals(deduce_str.get(deduce_str.size()-1))){ 37 | input_cache.remove(0); 38 | deduce_str.remove(deduce_str.size()-1); 39 | continue; 40 | } 41 | } catch (Exception e) { 42 | // TODO: handle exception 43 | e.printStackTrace(); 44 | } 45 | 46 | 47 | // 匹配字符 48 | leftandinput = deduce_str.get(deduce_str.size()-1)+"-"+input_cache.get(0); 49 | // if(input_cache.get(0)==null) 50 | // { 51 | // leftandinput = leftandinput+"$"; 52 | // } 53 | // 能够找到匹配的 54 | if((right=predictmap.get(leftandinput))!=null){ 55 | 56 | // 输出产生式和推导过程 57 | process = ""; 58 | for (int i=deduce_str.size()-1;i>-1;i--) { 59 | process = process+deduce_str.get(i)+" "; 60 | } 61 | tbmodel_lex_result.addRow(new String[]{process, deduce_str.get(deduce_str.size()-1)+" -> "+right}); 62 | 63 | // 删掉产生的字符,压入堆栈 64 | deduce_str.remove(deduce_str.size()-1); 65 | if(right.equals("$")){ 66 | // 只弹不压 67 | } 68 | else { 69 | String[] arg = right.split(" "); 70 | for(int i=arg.length-1;i>-1;i--){ 71 | // 反向压入堆栈 72 | deduce_str.add(arg[i]); 73 | } 74 | } 75 | 76 | } 77 | // 否则的话报错 78 | else { 79 | // 重新书写process 80 | process=""; 81 | for (int i=deduce_str.size()-1;i>-1;i--) { 82 | process = process+deduce_str.get(i)+" "; 83 | } 84 | tbmodel_lex_result.addRow(new String[]{process, "ERROR! 无法识别的字符"+input_cache.get(0)+"产生式"+leftandinput}); 85 | input_cache.remove(0); 86 | } 87 | } 88 | } 89 | 90 | // 获得预测分析表中的产生式以及对应的select集 91 | // 存储方式为键值对的形式 92 | public void getPredictMap(){ 93 | String text_line; 94 | String left; 95 | String symbol; 96 | String right; 97 | try { 98 | // 初始化 99 | predictmap = new HashMap(); 100 | // 采用随机读取方式 101 | File file = new File("predictldy.txt"); 102 | RandomAccessFile predictfile = new RandomAccessFile(file,"r"); 103 | while ((text_line = predictfile.readLine())!=null){ 104 | left = text_line.split("#")[0]; 105 | symbol = (text_line.split("#")[1]).split("->")[0].trim(); 106 | right = (text_line.split("#")[1]).split("->")[1].trim(); 107 | predictmap.put(left+"-"+symbol, right); 108 | 109 | } 110 | predictfile.close(); 111 | 112 | } catch (Exception e) { 113 | // TODO: handle exception 114 | e.printStackTrace(); 115 | } 116 | 117 | } 118 | 119 | 120 | } -------------------------------------------------------------------------------- /semantic/src/Production.java: -------------------------------------------------------------------------------- 1 | import java.util.List; 2 | 3 | public class Production { 4 | 5 | int no; 6 | String left; 7 | String[] right; 8 | List select; 9 | 10 | public String getError(){ 11 | return null; 12 | } 13 | 14 | public String getSolution(){ 15 | return null; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | String ret=left+" -->"; 21 | 22 | if(right.length==0) 23 | ret+=" ξ"; 24 | 25 | for(int i=0;i getSelect() { 33 | return select; 34 | } 35 | 36 | public void setSelect(List select) { 37 | this.select = select; 38 | } 39 | 40 | public int getNo() { 41 | return no; 42 | } 43 | 44 | public String getLeft() { 45 | return left; 46 | } 47 | 48 | public String[] getRight() { 49 | return right; 50 | } 51 | 52 | public Production(){} 53 | 54 | public Production(int no, String left) { 55 | this.no = no; 56 | this.left = left; 57 | this.right = new String[0]; 58 | // this.canBeBlank=true; 59 | } 60 | 61 | public Production(int no, String left, String symbol1) { 62 | this.no = no; 63 | this.left = left; 64 | this.right = new String[1]; 65 | this.right[0]=symbol1; 66 | } 67 | 68 | public Production(int no, String left, String symbol1, String symbol2) { 69 | this.no = no; 70 | this.left = left; 71 | this.right = new String[2]; 72 | this.right[0]=symbol1; 73 | this.right[1]=symbol2; 74 | } 75 | 76 | public Production(int no, String left, String symbol1, String symbol2, String symbol3) { 77 | this.no = no; 78 | this.left = left; 79 | this.right = new String[3]; 80 | this.right[0]=symbol1; 81 | this.right[1]=symbol2; 82 | this.right[2]=symbol3; 83 | } 84 | 85 | public Production(int no, String left, String symbol1, String symbol2, String symbol3, 86 | String symbol4) { 87 | this.no = no; 88 | this.left = left; 89 | this.right = new String[4]; 90 | this.right[0]=symbol1; 91 | this.right[1]=symbol2; 92 | this.right[2]=symbol3; 93 | this.right[3]=symbol4; 94 | } 95 | 96 | public Production(int no, String left, String symbol1, String symbol2, String symbol3, 97 | String symbol4, String symbol5) { 98 | this.no = no; 99 | this.left = left; 100 | this.right = new String[5]; 101 | this.right[0]=symbol1; 102 | this.right[1]=symbol2; 103 | this.right[2]=symbol3; 104 | this.right[3]=symbol4; 105 | this.right[4]=symbol5; 106 | } 107 | 108 | public Production(int no, String left, String symbol1, String symbol2, String symbol3, 109 | String symbol4, String symbol5, String symbol6) { 110 | this.no = no; 111 | this.left = left; 112 | this.right = new String[6]; 113 | this.right[0]=symbol1; 114 | this.right[1]=symbol2; 115 | this.right[2]=symbol3; 116 | this.right[3]=symbol4; 117 | this.right[4]=symbol5; 118 | this.right[5]=symbol6; 119 | } 120 | 121 | public Production(int no, String left, String symbol1, String symbol2, String symbol3, 122 | String symbol4, String symbol5, String symbol6, String symbol7) { 123 | this.no = no; 124 | this.left = left; 125 | this.right = new String[7]; 126 | this.right[0]=symbol1; 127 | this.right[1]=symbol2; 128 | this.right[2]=symbol3; 129 | this.right[3]=symbol4; 130 | this.right[4]=symbol5; 131 | this.right[5]=symbol6; 132 | this.right[6]=symbol7; 133 | } 134 | 135 | public Production(int no, String left, String symbol1, String symbol2, String symbol3, 136 | String symbol4, String symbol5, String symbol6, String symbol7, String symbol8) { 137 | this.no = no; 138 | this.left = left; 139 | this.right = new String[8]; 140 | this.right[0]=symbol1; 141 | this.right[1]=symbol2; 142 | this.right[2]=symbol3; 143 | this.right[3]=symbol4; 144 | this.right[4]=symbol5; 145 | this.right[5]=symbol6; 146 | this.right[6]=symbol7; 147 | this.right[7]=symbol8; 148 | } 149 | 150 | public Production(int no, String left, String symbol1, String symbol2, String symbol3, 151 | String symbol4, String symbol5, String symbol6, String symbol7, String symbol8, 152 | String symbol9) { 153 | this.no = no; 154 | this.left = left; 155 | this.right = new String[9]; 156 | this.right[0]=symbol1; 157 | this.right[1]=symbol2; 158 | this.right[2]=symbol3; 159 | this.right[3]=symbol4; 160 | this.right[4]=symbol5; 161 | this.right[5]=symbol6; 162 | this.right[6]=symbol7; 163 | this.right[7]=symbol8; 164 | this.right[8]=symbol9; 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /semantic/src/Token.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | public class Token implements Cloneable{ 5 | 6 | //标识符表 7 | static List id_list; 8 | 9 | String name; 10 | String value=null; 11 | String source; 12 | 13 | public static List getId_list() { 14 | return id_list; 15 | } 16 | 17 | public static void freeId_list(){ 18 | id_list=new ArrayList(); 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public String getValue() { 26 | return value; 27 | } 28 | 29 | public String getSource() { 30 | return source; 31 | } 32 | 33 | public Token(){} 34 | 35 | public Token(String name,String source){ 36 | this.name=name; 37 | this.source=source; 38 | 39 | if(source==null) 40 | return; 41 | 42 | if(name.equals("int")||name.equals("unsigned")||name.equals("long")||name.equals("long_unsigned")){ 43 | 44 | long k;//k代表k进制 45 | int begin;//从source的begin号字符开始算数 46 | 47 | if(source.charAt(0)=='0'){ 48 | if(source.length()==1||source.equals("0l")||source.equals("0L") 49 | ||source.equals("0U")||source.equals("0u") 50 | ||source.equals("0LU")||source.equals("0Lu") 51 | ||source.equals("0lU")||source.equals("0lu")){ 52 | this.value="0"; 53 | return; 54 | } 55 | 56 | if(source.charAt(1)=='x' || source.charAt(1)=='X'){ 57 | k=16; 58 | begin=2; 59 | }else if(source.charAt(1)>='0' && source.charAt(1)<='7'){ 60 | k=8; 61 | begin=1; 62 | }else{ 63 | throw new IllegalArgumentException("整形常量\'"+source+"\'的第二个字符不合法"); 64 | } 65 | 66 | }else if(source.charAt(0)>='1' && source.charAt(0)<='9'){ 67 | 68 | k=10; 69 | begin=0; 70 | 71 | }else{ 72 | throw new IllegalArgumentException("整形常量\'"+source+"\'的首字符必须是数字"); 73 | } 74 | 75 | long ret=0; 76 | for(int i=begin;ip1;i--){ 113 | xiaoshubu+=(double)char_to_int(source.charAt(i)); 114 | xiaoshubu/=10.0; 115 | } 116 | 117 | long zhishu=0; 118 | for(int i=p3+1;i=0 && source.charAt(p3)=='-') 128 | zhishu=-zhishu; 129 | 130 | if(p3<0) 131 | zhishu=0; 132 | 133 | // System.out.println("zhengbu = "+zhengbu); 134 | // System.out.println("xiaoshubu = "+xiaoshubu); 135 | // System.out.println("zhishu = "+zhishu); 136 | this.value=((zhengbu+xiaoshubu)*Math.pow(10.0,zhishu))+""; 137 | }else if(name.equals("char")){ 138 | 139 | if(source.charAt(1)=='\\'){ 140 | 141 | int ret=0; 142 | 143 | char temp=source.charAt(2); 144 | 145 | switch(temp){ 146 | case 'x': 147 | ret+=char_to_int(source.charAt(3)); 148 | if(source.charAt(4)!='\''){ 149 | ret*=16; 150 | ret+=char_to_int(source.charAt(4)); 151 | } 152 | break; 153 | case 'n': 154 | ret='\n'; 155 | break; 156 | case 'r': 157 | ret='\r'; 158 | break; 159 | case 't': 160 | ret='\t'; 161 | break; 162 | case 'v': 163 | ret=11; 164 | break; 165 | case 'b': 166 | ret='\b'; 167 | break; 168 | case 'f': 169 | ret='\f'; 170 | break; 171 | case 'a': 172 | ret=7; 173 | break; 174 | default: 175 | if(source.charAt(2)>='0' && source.charAt(2)<='7'){ 176 | ret+=source.charAt(2)-'0'; 177 | 178 | if(source.charAt(3)!='\''){ 179 | ret*=8; 180 | ret+=source.charAt(3)-'0'; 181 | 182 | if(source.charAt(4)!='\''){ 183 | ret*=8; 184 | ret+=source.charAt(4)-'0'; 185 | } 186 | } 187 | }else{ 188 | ret=source.charAt(2); 189 | } 190 | } 191 | 192 | this.value=ret+""; 193 | 194 | }else{ 195 | this.value=(int)source.charAt(1)+""; 196 | } 197 | }else if(name.equals("string")){ 198 | this.value=source.substring(1, source.length()-1); 199 | }else if(name.equals("id")){ 200 | int temp=search_id_list(source); 201 | 202 | if(temp>=0){ 203 | this.value=temp+""; 204 | }else{ 205 | id_list.add(source); 206 | this.value=(id_list.size()-1)+""; 207 | } 208 | } 209 | } 210 | 211 | public Token clone(){ 212 | try { 213 | return (Token)super.clone(); 214 | } catch (CloneNotSupportedException e) { 215 | // TODO Auto-generated catch block 216 | e.printStackTrace(); 217 | return null; 218 | } 219 | } 220 | 221 | private static int char_to_int(char c){ 222 | if(c>='0' && c<='9'){ 223 | return c-'0'; 224 | }else if(c>='a' && c<='f'){ 225 | return c-'a'+10; 226 | }else if(c>='A' && c<='F'){ 227 | return c-'A'+10; 228 | }else{ 229 | return -1; 230 | } 231 | } 232 | 233 | private static int search_id_list(String id){ 234 | for(int i=0;i lex_result_stack = text_lex.get_Lex_Result(); 167 | ArrayList> lex_error_stack = text_lex.get_Lex_Error(); 168 | 169 | // 若是存在词法分析错误 170 | if(lex_error_stack.size()!=0){ 171 | JOptionPane.showMessageDialog(main_panel, "词法分析阶段出现错误!", "提示", JOptionPane.ERROR_MESSAGE); 172 | } 173 | else { 174 | // 句法分析 175 | TextParse textParse = new TextParse(lex_result_stack, tbmodel_lex_error); 176 | textParse.Parsing(); 177 | } 178 | 179 | 180 | } 181 | } 182 | else if(e.getSource() == btn_cleardata){ 183 | ta_input.setText(""); 184 | clearTableData(); 185 | } 186 | else if(e.getSource() == file_open){ 187 | String file_name; 188 | JFileChooser file_open_filechooser = new JFileChooser(); 189 | file_open_filechooser.setCurrentDirectory(new File(".")); 190 | file_open_filechooser.setFileSelectionMode(JFileChooser.FILES_ONLY); 191 | int result = file_open_filechooser.showOpenDialog(main_panel); 192 | // 证明有选择 193 | if (result==JFileChooser.APPROVE_OPTION) { 194 | file_name = file_open_filechooser.getSelectedFile().getPath(); 195 | // 读取文件,写到JTextArea里面 196 | File file = new File(file_name); 197 | try{ 198 | InputStream in = new FileInputStream(file); 199 | int tempbyte; 200 | while ((tempbyte=in.read()) != -1) { 201 | ta_input.append(""+(char)tempbyte); 202 | } 203 | in.close(); 204 | } 205 | catch(Exception event){ 206 | event.printStackTrace(); 207 | } 208 | } 209 | 210 | } 211 | else if(e.getSource() == exit){ 212 | System.exit(1); 213 | } 214 | else { 215 | System.out.println("nothing!"); 216 | } 217 | } 218 | 219 | public void clearTableData(){ 220 | // System.out.println(tbmodel_lex_result.getRowCount()); 221 | // 事先要是不给他们赋值的话就会造成,tbmodel_lex_error在删除的过程中会不断 222 | // 地减少,然后就会出现很蛋疼的删不干净的情况 223 | int error_rows = tbmodel_lex_error.getRowCount(); 224 | int result_rows = tbmodel_lex_result.getRowCount(); 225 | for(int i=0;i productions; 10 | ArrayList terminals; 11 | ArrayList nonterminals; 12 | HashMap> firsts; 13 | HashMap> follows; 14 | 15 | public AnalyseList(){ 16 | productions = new ArrayList(); 17 | terminals = new ArrayList(); 18 | nonterminals = new ArrayList(); 19 | firsts = new HashMap>(); 20 | follows = new HashMap>(); 21 | 22 | setProductions(); 23 | setNonTerminals(); 24 | setTerminals(); 25 | 26 | getFirst(); 27 | getFollow(); 28 | getSelect(); 29 | 30 | Predict(); 31 | 32 | } 33 | 34 | 35 | 36 | // 从文件中读取产生式 37 | public void setProductions(){ 38 | try { 39 | File file = new File("grammar.txt"); 40 | RandomAccessFile randomfile = new RandomAccessFile(file, "r"); 41 | String line; 42 | String left; 43 | String right; 44 | Production production; 45 | while ((line=randomfile.readLine())!=null) { 46 | left = line.split("->")[0].trim(); 47 | right = line.split("->")[1].trim(); 48 | production = new Production(left, right.split(" ")); 49 | productions.add(production); 50 | } 51 | randomfile.close(); 52 | } catch (Exception e) { 53 | // TODO: handle exception 54 | e.printStackTrace(); 55 | } 56 | 57 | } 58 | 59 | // 获得非终结符集 60 | public void setNonTerminals(){ 61 | try { 62 | File file = new File("grammar.txt"); 63 | RandomAccessFile randomfile = new RandomAccessFile(file, "r"); 64 | String line; 65 | String left; 66 | while ((line=randomfile.readLine())!=null) { 67 | left = line.split("->")[0].trim(); 68 | if(nonterminals.contains(left)){ 69 | continue; 70 | } 71 | else { 72 | nonterminals.add(left); 73 | } 74 | } 75 | randomfile.close(); 76 | } catch (Exception e) { 77 | // TODO: handle exception 78 | e.printStackTrace(); 79 | } 80 | } 81 | 82 | // 获得终结符集,依赖于获得产生式函数 83 | public void setTerminals(){ 84 | // 遍历所有的产生式 85 | String[] rights; 86 | for (int i = 0; i < productions.size(); i++) { 87 | rights = productions.get(i).returnRights(); 88 | // 从右侧寻找终结符 89 | for (int j = 0; j < rights.length; j++) { 90 | if(nonterminals.contains(rights[j])||rights[j].equals("$")){ 91 | continue; 92 | } 93 | else { 94 | terminals.add(rights[j]); 95 | } 96 | } 97 | } 98 | } 99 | 100 | // 获取First集 101 | public void getFirst(){ 102 | // 终结符全部求出first集 103 | ArrayList first; 104 | for (int i = 0; i < terminals.size(); i++) { 105 | first = new ArrayList(); 106 | first.add(terminals.get(i)); 107 | firsts.put(terminals.get(i), first); 108 | } 109 | // 给所有非终结符注册一下 110 | for (int i = 0; i < nonterminals.size(); i++) { 111 | first = new ArrayList(); 112 | firsts.put(nonterminals.get(i), first); 113 | } 114 | 115 | boolean flag; 116 | while (true) { 117 | flag = true; 118 | String left; 119 | String right; 120 | String[] rights; 121 | for (int i = 0; i < productions.size(); i++) { 122 | left = productions.get(i).returnLeft(); 123 | rights = productions.get(i).returnRights(); 124 | for (int j = 0; j < rights.length; j++) { 125 | right = rights[j]; 126 | // right是否存在,遇到空怎么办 127 | if(!right.equals("$")){ 128 | for (int l = 0; l < firsts.get(right).size(); l++) { 129 | if(firsts.get(left).contains(firsts.get(right).get(l))){ 130 | continue; 131 | } 132 | else { 133 | firsts.get(left).add(firsts.get(right).get(l)); 134 | flag=false; 135 | } 136 | } 137 | } 138 | if (isCanBeNull(right)) { 139 | continue; 140 | } 141 | else { 142 | break; 143 | } 144 | } 145 | } 146 | if (flag==true) { 147 | break; 148 | } 149 | 150 | } 151 | // 非终结符的first集 152 | } 153 | 154 | // 获得Follow集 155 | public void getFollow(){ 156 | // 所有非终结符的follow集初始化一下 157 | ArrayList follow; 158 | for (int i = 0; i < nonterminals.size(); i++) { 159 | follow = new ArrayList(); 160 | follows.put(nonterminals.get(i), follow); 161 | } 162 | // 将#加入到follow(S)中 163 | follows.get("S").add("#"); 164 | boolean flag; 165 | boolean fab; 166 | while (true) { 167 | flag = true; 168 | // 循环 169 | for (int i = 0; i < productions.size(); i++) { 170 | String left; 171 | String right; 172 | String[] rights; 173 | rights = productions.get(i).returnRights(); 174 | for (int j = 0; j < rights.length; j++) { 175 | right = rights[j]; 176 | 177 | // 非终结符 178 | if (nonterminals.contains(right)) { 179 | fab = true; 180 | for(int k=j+1;k follow = new ArrayList(); 239 | ArrayList first = new ArrayList(); 240 | 241 | for (int i = 0; i < productions.size(); i++) { 242 | left = productions.get(i).returnLeft(); 243 | rights = productions.get(i).returnRights(); 244 | if(rights[0].equals("$")){ 245 | // select(i) = follow(A) 246 | follow = follows.get(left); 247 | for (int j = 0; j < follow.size(); j++) { 248 | if(productions.get(i).select.contains(follow.get(j))){ 249 | continue; 250 | } 251 | else { 252 | productions.get(i).select.add(follow.get(j)); 253 | } 254 | } 255 | } 256 | else { 257 | boolean flag = true; 258 | for (int j = 0; j < rights.length; j++) { 259 | right = rights[j]; 260 | first = firsts.get(right); 261 | for (int v = 0; v < first.size(); v++) { 262 | if (productions.get(i).select.contains(first.get(v))) { 263 | continue; 264 | } 265 | else { 266 | productions.get(i).select.add(first.get(v)); 267 | } 268 | } 269 | if(isCanBeNull(right)){ 270 | continue; 271 | } 272 | else { 273 | flag = false; 274 | break; 275 | } 276 | } 277 | if (flag) { 278 | follow = follows.get(left); 279 | for (int j = 0; j < follow.size(); j++) { 280 | if (productions.get(i).select.contains(follow.get(j))) { 281 | continue; 282 | } 283 | else { 284 | // 刚刚这里出现了一个问题,已经被解决啦 285 | productions.get(i).select.add(follow.get(j)); 286 | } 287 | } 288 | } 289 | } 290 | } 291 | } 292 | 293 | // 生成产生式 294 | public void Predict(){ 295 | Production production; 296 | String line; 297 | String[] rights; 298 | try { 299 | File file = new File("predictldy.txt"); 300 | RandomAccessFile randomfile = new RandomAccessFile(file,"rw"); 301 | for (int i = 0; i < productions.size(); i++) { 302 | production = productions.get(i); 303 | for (int j = 0; j < production.select.size(); j++) { 304 | line = production.returnLeft()+"#"+production.select.get(j)+" ->"; 305 | rights = production.returnRights(); 306 | for (int v = 0; v < rights.length; v++) { 307 | line = line+" "+rights[v]; 308 | } 309 | line = line+"\n"; 310 | // 写入文件 311 | randomfile.writeBytes(line); 312 | } 313 | } 314 | randomfile.close(); 315 | 316 | } catch (Exception e) { 317 | // TODO: handle exception 318 | e.printStackTrace(); 319 | } 320 | 321 | } 322 | 323 | // 判断是否是终结符 324 | public boolean isTerminal(String symbol){ 325 | if(terminals.contains(symbol)) 326 | return true; 327 | else { 328 | return false; 329 | } 330 | } 331 | 332 | // 判断是否产生$ 333 | public boolean isCanBeNull(String symbol){ 334 | String[] rights; 335 | for (int i = 0; i < productions.size(); i++) { 336 | // 找到产生式 337 | if (productions.get(i).returnLeft().equals(symbol)) { 338 | rights = productions.get(i).returnRights(); 339 | if (rights[0].equals("$")) { 340 | return true; 341 | } 342 | } 343 | } 344 | return false; 345 | } 346 | } -------------------------------------------------------------------------------- /semantic/src/ClientGui.java: -------------------------------------------------------------------------------- 1 | import java.awt.Color; 2 | import java.awt.event.ActionEvent; 3 | import java.awt.event.ActionListener; 4 | import java.io.File; 5 | import java.io.FileInputStream; 6 | import java.io.InputStream; 7 | import java.util.ArrayList; 8 | import java.util.HashMap; 9 | 10 | import javax.swing.JButton; 11 | import javax.swing.JFileChooser; 12 | import javax.swing.JFrame; 13 | import javax.swing.JLabel; 14 | import javax.swing.JMenu; 15 | import javax.swing.JMenuBar; 16 | import javax.swing.JMenuItem; 17 | import javax.swing.JOptionPane; 18 | import javax.swing.JPanel; 19 | import javax.swing.JScrollPane; 20 | import javax.swing.JTable; 21 | import javax.swing.JTextArea; 22 | import javax.swing.table.DefaultTableModel; 23 | 24 | 25 | public class ClientGui{ 26 | public static void main(String[] args){ 27 | LexFrame lexframe = new LexFrame(); 28 | lexframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 29 | lexframe.setResizable(false); 30 | lexframe.setVisible(true); 31 | AnalyseList analyse = new AnalyseList(); 32 | 33 | } 34 | public ClientGui() { 35 | // TODO Auto-generated constructor stub 36 | } 37 | } 38 | class LexFrame extends JFrame implements ActionListener{ 39 | 40 | /** 41 | * 42 | */ 43 | private static final long serialVersionUID = 1L; 44 | 45 | private JPanel main_panel; 46 | 47 | private JMenuBar main_menu_bar; 48 | private JMenu menu_file; 49 | private JMenu menu_run; 50 | private JMenuItem file_open; 51 | private JMenuItem file_save; 52 | private JMenuItem file_saveas; 53 | private JMenuItem exit; 54 | private JMenuItem run_lex; 55 | 56 | private JLabel lb_lex_result; 57 | private JLabel lb_lex_error; 58 | private JLabel lb_text_edit; 59 | private JLabel lb_symbol; 60 | private JLabel lb_triples; 61 | 62 | private JButton btn_start_lex; 63 | private JButton btn_cleardata; 64 | private JTextArea ta_input; 65 | private JScrollPane scrollpane_input; 66 | 67 | // 输出词法分析结果 68 | private JTable tb_lex_result; 69 | private DefaultTableModel tbmodel_lex_result; 70 | private JScrollPane scrollpane_lex_result; 71 | // 输出句法分析结果 72 | private JTable tb_lex_error; 73 | private DefaultTableModel tbmodel_lex_error; 74 | private JScrollPane scrollpane_lex_error; 75 | 76 | // 输出符号表 77 | private JTable tb_symbol_list; 78 | private DefaultTableModel tbmodel_symbol_list; 79 | private JScrollPane scrollpane_symbol_list; 80 | // 输出三地址指令 81 | private JTable tb_triples; 82 | private DefaultTableModel tbmodel_triples; 83 | private JScrollPane scrollpane_triples; 84 | 85 | public LexFrame(){ 86 | this.setTitle("语义分析器"); 87 | this.setSize(1300,800); 88 | initPanel(); 89 | } 90 | 91 | public void initPanel(){ 92 | main_menu_bar = new JMenuBar(); 93 | menu_file = new JMenu("文件"); 94 | menu_run = new JMenu("运行"); 95 | 96 | file_open = new JMenuItem("打开"); 97 | file_save = new JMenuItem("保存"); 98 | file_saveas = new JMenuItem("另存为"); 99 | exit = new JMenuItem("退出"); 100 | file_open.addActionListener(this); 101 | exit.addActionListener(this); 102 | menu_file.add(file_open); 103 | menu_file.add(file_save); 104 | menu_file.add(file_saveas); 105 | menu_file.add(exit); 106 | main_menu_bar.add(menu_file); 107 | 108 | run_lex = new JMenuItem("运行"); 109 | run_lex.addActionListener(this); 110 | menu_run.add(run_lex); 111 | main_menu_bar.add(menu_run); 112 | this.setJMenuBar(main_menu_bar); 113 | 114 | main_panel = new JPanel(); 115 | main_panel.setLayout(null); 116 | lb_text_edit = new JLabel("文本编辑区"); 117 | main_panel.add(lb_text_edit); 118 | lb_text_edit.setBounds(10, 10, 70, 20); 119 | 120 | ta_input = new JTextArea(); 121 | scrollpane_input = new JScrollPane(ta_input); 122 | main_panel.add(scrollpane_input); 123 | scrollpane_input.setBounds(10, 40, 400, 300); 124 | scrollpane_input.setRowHeaderView(new LineNumberHeaderView()); 125 | 126 | lb_lex_result = new JLabel("词法分析结果"); 127 | main_panel.add(lb_lex_result); 128 | lb_lex_result.setBounds(450, 10, 80, 20); 129 | 130 | tbmodel_lex_result = new DefaultTableModel(null, new String[]{"名称", "值"}); 131 | tb_lex_result = new JTable(tbmodel_lex_result); 132 | tb_lex_result.setEnabled(false); 133 | scrollpane_lex_result = new JScrollPane(tb_lex_result); 134 | main_panel.add(scrollpane_lex_result); 135 | scrollpane_lex_result.setBounds(450, 40, 360, 300); 136 | 137 | lb_symbol = new JLabel("符号表"); 138 | main_panel.add(lb_symbol); 139 | lb_symbol.setBounds(830, 10, 80, 20); 140 | 141 | tbmodel_symbol_list = new DefaultTableModel(null, new String[]{"变量名称", "所属类型", "长度", "内存地址"}); 142 | tb_symbol_list = new JTable(tbmodel_symbol_list); 143 | tb_symbol_list.setEnabled(false); 144 | scrollpane_symbol_list = new JScrollPane(tb_symbol_list); 145 | main_panel.add(scrollpane_symbol_list); 146 | scrollpane_symbol_list.setBounds(830, 40, 360, 300); 147 | 148 | btn_start_lex = new JButton("运行"); 149 | main_panel.add(btn_start_lex); 150 | btn_start_lex.setBounds(200, 350, 100, 20); 151 | btn_start_lex.addActionListener(this); 152 | 153 | btn_cleardata = new JButton("清空"); 154 | main_panel.add(btn_cleardata); 155 | btn_cleardata.setBounds(330, 350, 60, 20); 156 | btn_cleardata.addActionListener(this); 157 | 158 | lb_lex_error = new JLabel("推导过程"); 159 | main_panel.add(lb_lex_error); 160 | lb_lex_error.setBounds(10, 360, 80, 20); 161 | 162 | tbmodel_lex_error = new DefaultTableModel(null, new String[]{"推导", "运用的产生式"}); 163 | tb_lex_error = new JTable(tbmodel_lex_error); 164 | tb_lex_error.setForeground(Color.BLUE); 165 | tb_lex_error.setEnabled(false); 166 | scrollpane_lex_error = new JScrollPane(tb_lex_error); 167 | main_panel.add(scrollpane_lex_error); 168 | scrollpane_lex_error.setBounds(10, 400, 800, 300); 169 | 170 | lb_triples = new JLabel("三地址指令"); 171 | main_panel.add(lb_triples); 172 | lb_triples.setBounds(830,360, 80, 20); 173 | 174 | tbmodel_triples = new DefaultTableModel(null, new String[]{"序号","三地址码"}); 175 | tb_triples = new JTable(tbmodel_triples); 176 | tb_triples.setEnabled(false); 177 | scrollpane_triples = new JScrollPane(tb_triples); 178 | main_panel.add(scrollpane_triples); 179 | scrollpane_triples.setBounds(830, 400, 360, 300); 180 | 181 | add(main_panel); 182 | } 183 | 184 | @Override 185 | public void actionPerformed(ActionEvent e) { 186 | // TODO Auto-generated method stub 187 | if ((e.getSource() == btn_start_lex) || (e.getSource() == run_lex)) { 188 | // 进行判定k 189 | clearTableData(); 190 | if(ta_input.getText().equals("")){ 191 | JOptionPane.showMessageDialog(main_panel, "您什么都没有输入啊!", "提示", JOptionPane.ERROR_MESSAGE); 192 | System.out.println("nothing input!"); 193 | } 194 | else { 195 | // 词法分析 196 | TextLex text_lex = new TextLex(ta_input.getText(), tbmodel_lex_result, tbmodel_lex_error); 197 | text_lex.scannerAll(); 198 | 199 | // 获得结果的表 200 | ArrayList lex_result_stack = text_lex.get_Lex_Result(); 201 | ArrayList> lex_error_stack = text_lex.get_Lex_Error(); 202 | 203 | // 若是存在词法分析错误 204 | if(lex_error_stack.size()!=0){ 205 | JOptionPane.showMessageDialog(main_panel, "词法分析阶段出现错误!", "提示", JOptionPane.ERROR_MESSAGE); 206 | } 207 | else { 208 | // 句法分析 209 | TextParse textParse = new TextParse(lex_result_stack, tbmodel_lex_error); 210 | textParse.Parsing(); 211 | // 语义分析 212 | SemanticAnalyse semanticanalyse = new SemanticAnalyse(ta_input.getText(), tbmodel_symbol_list, tbmodel_triples); 213 | semanticanalyse.Parsing(); 214 | } 215 | 216 | } 217 | } 218 | else if(e.getSource() == btn_cleardata){ 219 | ta_input.setText(""); 220 | clearTableData(); 221 | } 222 | else if(e.getSource() == file_open){ 223 | String file_name; 224 | JFileChooser file_open_filechooser = new JFileChooser(); 225 | file_open_filechooser.setCurrentDirectory(new File(".")); 226 | file_open_filechooser.setFileSelectionMode(JFileChooser.FILES_ONLY); 227 | int result = file_open_filechooser.showOpenDialog(main_panel); 228 | // 证明有选择 229 | if (result==JFileChooser.APPROVE_OPTION) { 230 | file_name = file_open_filechooser.getSelectedFile().getPath(); 231 | // 读取文件,写到JTextArea里面 232 | File file = new File(file_name); 233 | try{ 234 | InputStream in = new FileInputStream(file); 235 | int tempbyte; 236 | while ((tempbyte=in.read()) != -1) { 237 | ta_input.append(""+(char)tempbyte); 238 | } 239 | in.close(); 240 | } 241 | catch(Exception event){ 242 | event.printStackTrace(); 243 | } 244 | } 245 | 246 | } 247 | else if(e.getSource() == exit){ 248 | System.exit(1); 249 | } 250 | else { 251 | System.out.println("nothing!"); 252 | } 253 | } 254 | 255 | public void clearTableData(){ 256 | // System.out.println(tbmodel_lex_result.getRowCount()); 257 | // 事先要是不给他们赋值的话就会造成,tbmodel_lex_error在删除的过程中会不断 258 | // 地减少,然后就会出现很蛋疼的删不干净的情况 259 | int error_rows = tbmodel_lex_error.getRowCount(); 260 | int result_rows = tbmodel_lex_result.getRowCount(); 261 | int triples_rows = tbmodel_triples.getRowCount(); 262 | int symbols_rows = tbmodel_symbol_list.getRowCount(); 263 | for(int i=0;i productions; 10 | ArrayList terminals; 11 | ArrayList nonterminals; 12 | HashMap> firsts; 13 | HashMap> follows; 14 | 15 | public AnalyseList(){ 16 | productions = new ArrayList(); 17 | terminals = new ArrayList(); 18 | nonterminals = new ArrayList(); 19 | firsts = new HashMap>(); 20 | follows = new HashMap>(); 21 | 22 | setProductions(); 23 | setNonTerminals(); 24 | setTerminals(); 25 | 26 | getFirst(); 27 | getFollow(); 28 | getSelect(); 29 | 30 | Predict(); 31 | 32 | } 33 | 34 | // 从文件中读取产生式 35 | public void setProductions(){ 36 | try { 37 | File file = new File("grammar.txt"); 38 | RandomAccessFile randomfile = new RandomAccessFile(file, "r"); 39 | String line; 40 | String left; 41 | String right; 42 | LProduction production; 43 | while ((line=randomfile.readLine())!=null) { 44 | left = line.split("->")[0].trim(); 45 | right = line.split("->")[1].trim(); 46 | production = new LProduction(left, right.split(" ")); 47 | productions.add(production); 48 | } 49 | randomfile.close(); 50 | } catch (Exception e) { 51 | // TODO: handle exception 52 | e.printStackTrace(); 53 | } 54 | 55 | } 56 | 57 | // 获得非终结符集 58 | public void setNonTerminals(){ 59 | try { 60 | File file = new File("grammar.txt"); 61 | RandomAccessFile randomfile = new RandomAccessFile(file, "r"); 62 | String line; 63 | String left; 64 | while ((line=randomfile.readLine())!=null) { 65 | left = line.split("->")[0].trim(); 66 | if(nonterminals.contains(left)){ 67 | continue; 68 | } 69 | else { 70 | nonterminals.add(left); 71 | } 72 | } 73 | randomfile.close(); 74 | } catch (Exception e) { 75 | // TODO: handle exception 76 | e.printStackTrace(); 77 | } 78 | } 79 | 80 | // 获得终结符集,依赖于获得产生式函数 81 | public void setTerminals(){ 82 | // 遍历所有的产生式 83 | String[] rights; 84 | for (int i = 0; i < productions.size(); i++) { 85 | rights = productions.get(i).returnRights(); 86 | // 从右侧寻找终结符 87 | for (int j = 0; j < rights.length; j++) { 88 | if(nonterminals.contains(rights[j])||rights[j].equals("$")){ 89 | continue; 90 | } 91 | else { 92 | terminals.add(rights[j]); 93 | } 94 | } 95 | } 96 | } 97 | 98 | // 获取First集 99 | public void getFirst(){ 100 | // 终结符全部求出first集 101 | ArrayList first; 102 | for (int i = 0; i < terminals.size(); i++) { 103 | first = new ArrayList(); 104 | first.add(terminals.get(i)); 105 | firsts.put(terminals.get(i), first); 106 | } 107 | // 给所有非终结符注册一下 108 | for (int i = 0; i < nonterminals.size(); i++) { 109 | first = new ArrayList(); 110 | firsts.put(nonterminals.get(i), first); 111 | } 112 | 113 | boolean flag; 114 | while (true) { 115 | flag = true; 116 | String left; 117 | String right; 118 | String[] rights; 119 | for (int i = 0; i < productions.size(); i++) { 120 | left = productions.get(i).returnLeft(); 121 | rights = productions.get(i).returnRights(); 122 | for (int j = 0; j < rights.length; j++) { 123 | right = rights[j]; 124 | // right是否存在,遇到空怎么办 125 | if(!right.equals("$")){ 126 | for (int l = 0; l < firsts.get(right).size(); l++) { 127 | if(firsts.get(left).contains(firsts.get(right).get(l))){ 128 | continue; 129 | } 130 | else { 131 | firsts.get(left).add(firsts.get(right).get(l)); 132 | flag=false; 133 | } 134 | } 135 | } 136 | if (isCanBeNull(right)) { 137 | continue; 138 | } 139 | else { 140 | break; 141 | } 142 | } 143 | } 144 | if (flag==true) { 145 | break; 146 | } 147 | 148 | } 149 | // 非终结符的first集 150 | } 151 | 152 | // 获得Follow集 153 | public void getFollow(){ 154 | // 所有非终结符的follow集初始化一下 155 | ArrayList follow; 156 | for (int i = 0; i < nonterminals.size(); i++) { 157 | follow = new ArrayList(); 158 | follows.put(nonterminals.get(i), follow); 159 | } 160 | // 将#加入到follow(S)中 161 | follows.get("S").add("#"); 162 | boolean flag; 163 | boolean fab; 164 | while (true) { 165 | flag = true; 166 | // 循环 167 | for (int i = 0; i < productions.size(); i++) { 168 | String left; 169 | String right; 170 | String[] rights; 171 | rights = productions.get(i).returnRights(); 172 | for (int j = 0; j < rights.length; j++) { 173 | right = rights[j]; 174 | 175 | // 非终结符 176 | if (nonterminals.contains(right)) { 177 | fab = true; 178 | for(int k=j+1;k follow = new ArrayList(); 237 | ArrayList first = new ArrayList(); 238 | 239 | for (int i = 0; i < productions.size(); i++) { 240 | left = productions.get(i).returnLeft(); 241 | rights = productions.get(i).returnRights(); 242 | if(rights[0].equals("$")){ 243 | // select(i) = follow(A) 244 | follow = follows.get(left); 245 | for (int j = 0; j < follow.size(); j++) { 246 | if(productions.get(i).select.contains(follow.get(j))){ 247 | continue; 248 | } 249 | else { 250 | productions.get(i).select.add(follow.get(j)); 251 | } 252 | } 253 | } 254 | else { 255 | boolean flag = true; 256 | for (int j = 0; j < rights.length; j++) { 257 | right = rights[j]; 258 | first = firsts.get(right); 259 | for (int v = 0; v < first.size(); v++) { 260 | if (productions.get(i).select.contains(first.get(v))) { 261 | continue; 262 | } 263 | else { 264 | productions.get(i).select.add(first.get(v)); 265 | } 266 | } 267 | if(isCanBeNull(right)){ 268 | continue; 269 | } 270 | else { 271 | flag = false; 272 | break; 273 | } 274 | } 275 | if (flag) { 276 | follow = follows.get(left); 277 | for (int j = 0; j < follow.size(); j++) { 278 | if (productions.get(i).select.contains(follow.get(j))) { 279 | continue; 280 | } 281 | else { 282 | // 刚刚这里出现了一个问题,已经被解决啦 283 | productions.get(i).select.add(follow.get(j)); 284 | } 285 | } 286 | } 287 | } 288 | } 289 | } 290 | 291 | // 生成产生式 292 | public void Predict(){ 293 | LProduction production; 294 | String line; 295 | String[] rights; 296 | try { 297 | File file = new File("predictldy.txt"); 298 | RandomAccessFile randomfile = new RandomAccessFile(file,"rw"); 299 | for (int i = 0; i < productions.size(); i++) { 300 | production = productions.get(i); 301 | for (int j = 0; j < production.select.size(); j++) { 302 | line = production.returnLeft()+"#"+production.select.get(j)+" ->"; 303 | rights = production.returnRights(); 304 | for (int v = 0; v < rights.length; v++) { 305 | line = line+" "+rights[v]; 306 | } 307 | line = line+"\n"; 308 | // 写入文件 309 | randomfile.writeBytes(line); 310 | } 311 | } 312 | randomfile.close(); 313 | 314 | } catch (Exception e) { 315 | // TODO: handle exception 316 | e.printStackTrace(); 317 | } 318 | 319 | } 320 | 321 | // 判断是否是终结符 322 | public boolean isTerminal(String symbol){ 323 | if(terminals.contains(symbol)) 324 | return true; 325 | else { 326 | return false; 327 | } 328 | } 329 | 330 | // 判断是否产生$ 331 | public boolean isCanBeNull(String symbol){ 332 | String[] rights; 333 | for (int i = 0; i < productions.size(); i++) { 334 | // 找到产生式 335 | if (productions.get(i).returnLeft().equals(symbol)) { 336 | rights = productions.get(i).returnRights(); 337 | if (rights[0].equals("$")) { 338 | return true; 339 | } 340 | } 341 | } 342 | return false; 343 | } 344 | } 345 | //产生式类 346 | class LProduction{ 347 | String left; 348 | String[] right; 349 | // 初始化select集 350 | ArrayList select = new ArrayList(); 351 | public LProduction(String left, String[] right){ 352 | this.left = left; 353 | this.right = right; 354 | } 355 | 356 | public String[] returnRights(){ 357 | return right; 358 | } 359 | 360 | public String returnLeft(){ 361 | return left; 362 | } 363 | } -------------------------------------------------------------------------------- /ldylex/src/TextLex.java: -------------------------------------------------------------------------------- 1 | import javax.swing.table.DefaultTableModel; 2 | 3 | 4 | public class TextLex{ 5 | 6 | private String text; 7 | private DefaultTableModel tbmodel_lex_result; 8 | private DefaultTableModel tbmodel_lex_error; 9 | private int text_length; 10 | private int row_number=1; 11 | String[] Key = {"main", "void", "int", "double", "char", "float", "printf", "class", "scanf", "else", "if", "return" ,"char","public", 12 | "static","true", "false", "private"}; 13 | 14 | public TextLex(String text, DefaultTableModel tb_lex_result, DefaultTableModel tb_lex_error){ 15 | this.text = text; 16 | this.tbmodel_lex_result = tb_lex_result; 17 | this.tbmodel_lex_error = tb_lex_error; 18 | text_length = text.length(); 19 | } 20 | 21 | public int isAlpha(char c){ 22 | if(((c<='z')&&(c>='a')) || ((c<='Z')&&(c>='A')) || (c=='_')) 23 | return 1; 24 | else 25 | return 0; 26 | } 27 | 28 | public int isNumber(char c){ 29 | if((c>='0')&&(c<='9')) 30 | return 1; 31 | else 32 | return 0; 33 | } 34 | 35 | public int isKey(String t){ 36 | for(int i=0;i': 148 | return handleMore(i, s); 149 | case '<': 150 | return handleLess(i, s); 151 | case '%': 152 | ch = text.charAt(++i); 153 | if (ch=='=') { 154 | // 输出运算符 155 | s = s+ch; 156 | printResult(s, "运算符"); 157 | return ++i; 158 | } 159 | else if(ch=='s'||ch=='c'||ch=='d'||ch=='f'||ch=='l'){ 160 | // 输出类型标识符 161 | s = s+ch; 162 | printResult(s, "输出类型标识符"); 163 | return ++i; 164 | } 165 | else { 166 | // 输出求余标识符 167 | printResult(s, "求余标识符"); 168 | return i; 169 | } 170 | default: 171 | // 输出暂时无法识别的字符,制表符也被当成了有问题的字符 172 | printError(row_number, s, "暂时无法识别的标识符"); 173 | return ++i; 174 | } 175 | } 176 | } 177 | 178 | public int handleFirstAlpha(int arg, String arg0){ 179 | int i=arg; 180 | String s = arg0; 181 | char ch=text.charAt(++i); 182 | while(isAlpha(ch)==1 || isNumber(ch)==1){ 183 | s = s+ch; 184 | ch=text.charAt(++i); 185 | } 186 | if(s.length()==1){ 187 | printResult(s, "字符常数"); 188 | return i; 189 | } 190 | // 到了结尾 191 | if(isKey(s)==1){ 192 | // 输出key 193 | printResult(s, "关键字"); 194 | return i; 195 | 196 | } 197 | else { 198 | // 输出普通的标识符 199 | printResult(s, "普通标识符"); 200 | return i; 201 | } 202 | } 203 | 204 | public int handleFirstNum(int arg, String arg0){ 205 | int i = arg; 206 | char ch = text.charAt(++i); 207 | String s = arg0; 208 | while(isNumber(ch)==1){ 209 | s = s+ch; 210 | ch = text.charAt(++i); 211 | } 212 | if((text.charAt(i)==' ')||(text.charAt(i)=='\t')||(text.charAt(i)=='\n')||(text.charAt(i)=='\r')||(text.charAt(i)=='\0')||ch==';'||ch==','){ 213 | // 到了结尾,输出数字 214 | printResult(s, "整数"); 215 | return i; 216 | } 217 | else if (ch=='E') { 218 | if (text.charAt(i+1)=='+') { 219 | s = s+ch; 220 | ch = text.charAt(++i); 221 | s = s+ch; 222 | ch = text.charAt(++i); 223 | while (isNumber(ch)==1) { 224 | s = s+ch; 225 | ch = text.charAt(++i); 226 | } 227 | if(ch=='\r'||ch=='\n'||ch==';'||ch=='\t'){ 228 | printResult(s, "科学计数"); 229 | return ++i; 230 | } 231 | else { 232 | printError(i, s, "浮点数错误"); 233 | return i; 234 | } 235 | } 236 | else if (isNumber(text.charAt(i+1))==1) { 237 | s = s+ch; 238 | ch = text.charAt(++i); 239 | while (isNumber(ch)==1) { 240 | s = s+ch; 241 | ch = text.charAt(++i); 242 | } 243 | if(ch=='\r'||ch=='\n'||ch==';'||ch=='\t'){ 244 | printResult(s, "科学计数"); 245 | return ++i; 246 | } 247 | else { 248 | printError(row_number, s, "浮点数错误"); 249 | return i; 250 | } 251 | } 252 | else { 253 | printError(row_number, s, "科学计数法错误"); 254 | return ++i; 255 | } 256 | } 257 | 258 | // 浮点数判断 259 | else if (text.charAt(i)=='.'&&(isNumber(text.charAt(i+1))==1)) { 260 | s = s +'.'; 261 | ch = text.charAt(++i); 262 | while (isNumber(ch)==1) { 263 | s = s+ch; 264 | ch = text.charAt(++i); 265 | } 266 | if (ch=='E') { 267 | if (text.charAt(i+1)=='+') { 268 | s = s+ch; 269 | ch = text.charAt(++i); 270 | s = s+ch; 271 | ch = text.charAt(++i); 272 | while (isNumber(ch)==1) { 273 | s = s+ch; 274 | ch = text.charAt(++i); 275 | } 276 | if(ch=='\r'||ch=='\n'||ch==';'||ch=='\t'){ 277 | printResult(s, "科学计数"); 278 | return ++i; 279 | } 280 | else { 281 | printError(i, s, "浮点数错误"); 282 | return i; 283 | } 284 | } 285 | else if (isNumber(text.charAt(i+1))==1) { 286 | s = s+ch; 287 | ch = text.charAt(++i); 288 | while (isNumber(ch)==1) { 289 | s = s+ch; 290 | ch = text.charAt(++i); 291 | } 292 | if(ch=='\r'||ch=='\n'||ch==';'||ch=='\t'){ 293 | printResult(s, "科学计数"); 294 | return ++i; 295 | } 296 | else { 297 | printError(row_number, s, "浮点数错误"); 298 | return i; 299 | } 300 | } 301 | else { 302 | printError(row_number, s, "科学计数法错误"); 303 | return ++i; 304 | } 305 | } 306 | else if (ch=='\n'||ch=='\r'||ch=='\t'||ch==' '||ch=='\0'||ch!=','||ch!=';') { 307 | printResult(s, "浮点数"); 308 | return i; 309 | } 310 | else if (ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='\0') { 311 | printResult(s, "浮点数"); 312 | return i; 313 | } 314 | else { 315 | while (ch!='\n'&&ch!='\t'&&ch!=' '&&ch!='\r'&&ch!='\0'&&ch!=';'&&ch!='.'&&ch!=',') { 316 | s = s+ch; 317 | ch = text.charAt(++i); 318 | } 319 | printError(row_number, s, "不合法的字符"); 320 | return i; 321 | } 322 | } 323 | else if (ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='\0') { 324 | printResult(s, "整数"); 325 | return i; 326 | } 327 | else { 328 | do { 329 | ch = text.charAt(i++); 330 | s = s+ch; 331 | } while ((text.charAt(i)!=' ')&&(text.charAt(i)!='\t')&&(text.charAt(i)!='\n')&&(text.charAt(i)!='\r')&&(text.charAt(i)!='\0')); 332 | printError(row_number, s, "错误的标识符"); 333 | return i; 334 | } 335 | } 336 | public int handleChar(int arg, String arg0){ 337 | String s = arg0; 338 | int i = arg; 339 | char ch = text.charAt(++i); 340 | while(ch!='\''){ 341 | if (ch=='\r'||ch=='\n') { 342 | row_number++; 343 | } 344 | else if(ch=='\0'){ 345 | printError(row_number, s, "单字符错误"); 346 | return i; 347 | } 348 | s = s+ch; 349 | ch = text.charAt(++i); 350 | } 351 | s = s+ch; 352 | System.out.println(s); 353 | if (s.length()==3||s.equals("\'"+"\\"+"t"+"\'")||s.equals("\'"+"\\"+"n"+"\'")||s.equals("\'"+"\\"+"r"+"\'")) { 354 | printResult(s, "单字符"); 355 | } 356 | else 357 | printError(row_number, s, "字符溢出"); 358 | return ++i; 359 | } 360 | 361 | // 单行注释处理 362 | public int handleSingleLineNote(int arg, String arg0){ 363 | String s = arg0; 364 | int i = arg; 365 | char ch = text.charAt(++i); 366 | while (ch!='\r'&&ch!='\n'&&ch!='\0') { 367 | s = s+ch; 368 | ch = text.charAt(++i); 369 | } 370 | printResult(s, "单行注释"); 371 | return i; 372 | } 373 | 374 | // 字符串处理 375 | public int handleString(int arg, String arg0){ 376 | String s = arg0; 377 | int i=arg; 378 | char ch = text.charAt(++i); 379 | while(ch!='"'){ 380 | if (ch=='\r'||ch=='\n') { 381 | row_number++; 382 | } 383 | else if(ch=='\0'){ 384 | printError(row_number, s, "字符串没有闭合"); 385 | return i; 386 | } 387 | s = s+ch; 388 | ch = text.charAt(++i); 389 | } 390 | s = s+ch; 391 | printResult(s, "字符串"); 392 | return ++i; 393 | } 394 | 395 | public int handlePlus(int arg, String arg0){ 396 | int i=arg; 397 | char ch = text.charAt(++i); 398 | String s = arg0; 399 | if (ch=='+'){ 400 | // 输出运算符 401 | s = s+ch; 402 | printResult(s, "运算符"); 403 | return ++i; 404 | } 405 | 406 | else if(ch=='='){ 407 | s = s+ch; 408 | // 输出运算符 409 | printResult(s, "运算符"); 410 | return ++i; 411 | } 412 | else{ 413 | // 输出运算符 414 | printResult(s, "运算符"); 415 | return i; 416 | } 417 | } 418 | 419 | // 处理注释,没有考虑不闭合的情况 420 | public int handleNote(int arg, String arg0){ 421 | int i = arg; 422 | char ch=text.charAt(++i); 423 | String s = arg0+ch; 424 | ch = text.charAt(++i); 425 | while (ch!='*' || ((i+1)'){ 478 | s = s+ch; 479 | // 输出运算符 480 | printResult(s, "运算符"); 481 | return ++i; 482 | } 483 | else{ 484 | // 输出运算符 485 | printResult(s, "运算符"); 486 | return i; 487 | } 488 | } 489 | 490 | public int handleLess(int arg, String arg0){ 491 | int i=arg; 492 | String s = arg0; 493 | char ch = text.charAt(++i); 494 | if (ch=='='){ 495 | s = s+ch; 496 | // 输出运算符 497 | printResult(s, "运算符"); 498 | return ++i; 499 | } 500 | 501 | else if(ch=='<'){ 502 | s = s+ch; 503 | // 输出运算符 504 | printResult(s, "运算符"); 505 | return ++i; 506 | } 507 | else{ 508 | // 输出运算符 509 | printResult(s, "运算符"); 510 | return i; 511 | } 512 | } 513 | 514 | public void printResult(String rs_value, String rs_name){ 515 | tbmodel_lex_result.addRow(new String[]{rs_value, rs_name}); 516 | } 517 | 518 | public void printError(int row_num, String rs_value, String rs_name) { 519 | tbmodel_lex_error.addRow(new String[]{row_num+"", rs_value, rs_name}); 520 | } 521 | 522 | } -------------------------------------------------------------------------------- /parsing/predictldy.txt: -------------------------------------------------------------------------------- 1 | S#int -> func funcs 2 | S#short -> func funcs 3 | S#long -> func funcs 4 | S#char -> func funcs 5 | S#float -> func funcs 6 | S#double -> func funcs 7 | S#void -> func funcs 8 | S#unsigned -> func funcs 9 | funcs#int -> func funcs 10 | funcs#short -> func funcs 11 | funcs#long -> func funcs 12 | funcs#char -> func funcs 13 | funcs#float -> func funcs 14 | funcs#double -> func funcs 15 | funcs#void -> func funcs 16 | funcs#unsigned -> func funcs 17 | func#int -> type IDN ( args ) func_body 18 | func#short -> type IDN ( args ) func_body 19 | func#long -> type IDN ( args ) func_body 20 | func#char -> type IDN ( args ) func_body 21 | func#float -> type IDN ( args ) func_body 22 | func#double -> type IDN ( args ) func_body 23 | func#void -> type IDN ( args ) func_body 24 | func#unsigned -> type IDN ( args ) func_body 25 | type#int -> int 26 | type#short -> short 27 | type#long -> long 28 | type#char -> char 29 | type#float -> float 30 | type#double -> double 31 | type#void -> void 32 | type#unsigned -> unsigned type 33 | args#int -> type IDN arg 34 | args#short -> type IDN arg 35 | args#long -> type IDN arg 36 | args#char -> type IDN arg 37 | args#float -> type IDN arg 38 | args#double -> type IDN arg 39 | args#void -> type IDN arg 40 | args#unsigned -> type IDN arg 41 | args#) -> $ 42 | arg#, -> , type IDN arg 43 | arg#) -> $ 44 | func_body#; -> ; 45 | func_body#{ -> block 46 | block#{ -> { define_stmts stmts } 47 | define_stmts#int -> define_stmt define_stmts 48 | define_stmts#short -> define_stmt define_stmts 49 | define_stmts#long -> define_stmt define_stmts 50 | define_stmts#char -> define_stmt define_stmts 51 | define_stmts#float -> define_stmt define_stmts 52 | define_stmts#double -> define_stmt define_stmts 53 | define_stmts#void -> define_stmt define_stmts 54 | define_stmts#unsigned -> define_stmt define_stmts 55 | define_stmts#continue -> $ 56 | define_stmts#break -> $ 57 | define_stmts#return -> $ 58 | define_stmts#while -> $ 59 | define_stmts#for -> $ 60 | define_stmts#do -> $ 61 | define_stmts#if -> $ 62 | define_stmts#switch -> $ 63 | define_stmts#( -> $ 64 | define_stmts#IDN -> $ 65 | define_stmts#FLOAT -> $ 66 | define_stmts#CHAR -> $ 67 | define_stmts#STR -> $ 68 | define_stmts#INT10 -> $ 69 | define_stmts#INT8 -> $ 70 | define_stmts#INT16 -> $ 71 | define_stmts#} -> $ 72 | define_stmt#int -> type IDN init vars ; 73 | define_stmt#short -> type IDN init vars ; 74 | define_stmt#long -> type IDN init vars ; 75 | define_stmt#char -> type IDN init vars ; 76 | define_stmt#float -> type IDN init vars ; 77 | define_stmt#double -> type IDN init vars ; 78 | define_stmt#void -> type IDN init vars ; 79 | define_stmt#unsigned -> type IDN init vars ; 80 | init#= -> = expression 81 | init#, -> $ 82 | init#; -> $ 83 | vars#, -> , IDN init vars 84 | vars#; -> $ 85 | stmts#continue -> stmt stmts 86 | stmts#break -> stmt stmts 87 | stmts#return -> stmt stmts 88 | stmts#while -> stmt stmts 89 | stmts#for -> stmt stmts 90 | stmts#do -> stmt stmts 91 | stmts#if -> stmt stmts 92 | stmts#switch -> stmt stmts 93 | stmts#( -> stmt stmts 94 | stmts#IDN -> stmt stmts 95 | stmts#FLOAT -> stmt stmts 96 | stmts#CHAR -> stmt stmts 97 | stmts#STR -> stmt stmts 98 | stmts#INT10 -> stmt stmts 99 | stmts#INT8 -> stmt stmts 100 | stmts#INT16 -> stmt stmts 101 | stmts#} -> $ 102 | stmts#case -> $ 103 | stmts#default -> $ 104 | stmt#( -> assign_stmt 105 | stmt#IDN -> assign_stmt 106 | stmt#FLOAT -> assign_stmt 107 | stmt#CHAR -> assign_stmt 108 | stmt#STR -> assign_stmt 109 | stmt#INT10 -> assign_stmt 110 | stmt#INT8 -> assign_stmt 111 | stmt#INT16 -> assign_stmt 112 | stmt#continue -> jump_stmt 113 | stmt#break -> jump_stmt 114 | stmt#return -> jump_stmt 115 | stmt#while -> iteration_stmt 116 | stmt#for -> iteration_stmt 117 | stmt#do -> iteration_stmt 118 | stmt#if -> branch_stmt 119 | stmt#switch -> branch_stmt 120 | assign_stmt#( -> expression ; 121 | assign_stmt#IDN -> expression ; 122 | assign_stmt#FLOAT -> expression ; 123 | assign_stmt#CHAR -> expression ; 124 | assign_stmt#STR -> expression ; 125 | assign_stmt#INT10 -> expression ; 126 | assign_stmt#INT8 -> expression ; 127 | assign_stmt#INT16 -> expression ; 128 | jump_stmt#continue -> continue ; 129 | jump_stmt#break -> break ; 130 | jump_stmt#return -> return isnull_expr ; 131 | iteration_stmt#while -> while ( logical_expression ) block_stmt 132 | iteration_stmt#for -> for ( isnull_expr ; isnull_expr ; isnull_expr ) block_stmt 133 | iteration_stmt#do -> do block_stmt while ( logical_expression ) ; 134 | branch_stmt#if -> if ( logical_expression ) block_stmt result 135 | result#else -> else block_stmt 136 | result#continue -> $ 137 | result#break -> $ 138 | result#return -> $ 139 | result#while -> $ 140 | result#for -> $ 141 | result#do -> $ 142 | result#if -> $ 143 | result#switch -> $ 144 | result#( -> $ 145 | result#IDN -> $ 146 | result#FLOAT -> $ 147 | result#CHAR -> $ 148 | result#STR -> $ 149 | result#INT10 -> $ 150 | result#INT8 -> $ 151 | result#INT16 -> $ 152 | result#} -> $ 153 | result#case -> $ 154 | result#default -> $ 155 | logical_expression#! -> ! expression bool_expression 156 | logical_expression#( -> expression bool_expression 157 | logical_expression#IDN -> expression bool_expression 158 | logical_expression#FLOAT -> expression bool_expression 159 | logical_expression#CHAR -> expression bool_expression 160 | logical_expression#STR -> expression bool_expression 161 | logical_expression#INT10 -> expression bool_expression 162 | logical_expression#INT8 -> expression bool_expression 163 | logical_expression#INT16 -> expression bool_expression 164 | bool_expression#&& -> lop expression bool_expression 165 | bool_expression#|| -> lop expression bool_expression 166 | bool_expression#) -> $ 167 | lop#&& -> && 168 | lop#|| -> || 169 | branch_stmt#switch -> switch ( IDN ) { case_stmt case_stmts default_stmt } 170 | case_stmts#case -> case_stmt case_stmts 171 | case_stmts#default -> $ 172 | case_stmt#case -> case const : stmts 173 | default_stmt#default -> default : stmts 174 | block_stmt#{ -> { stmts } 175 | isnull_expr#( -> expression 176 | isnull_expr#IDN -> expression 177 | isnull_expr#FLOAT -> expression 178 | isnull_expr#CHAR -> expression 179 | isnull_expr#STR -> expression 180 | isnull_expr#INT10 -> expression 181 | isnull_expr#INT8 -> expression 182 | isnull_expr#INT16 -> expression 183 | isnull_expr#; -> $ 184 | isnull_expr#) -> $ 185 | isnull_expr#, -> $ 186 | expression#( -> value operation 187 | expression#IDN -> value operation 188 | expression#FLOAT -> value operation 189 | expression#CHAR -> value operation 190 | expression#STR -> value operation 191 | expression#INT10 -> value operation 192 | expression#INT8 -> value operation 193 | expression#INT16 -> value operation 194 | operation#> -> compare_op value 195 | operation#>= -> compare_op value 196 | operation#< -> compare_op value 197 | operation#<= -> compare_op value 198 | operation#== -> compare_op value 199 | operation#!= -> compare_op value 200 | operation#= -> equal_op value 201 | operation#+= -> equal_op value 202 | operation#-= -> equal_op value 203 | operation#*= -> equal_op value 204 | operation#/= -> equal_op value 205 | operation#%= -> equal_op value 206 | operation#, -> $ 207 | operation#; -> $ 208 | operation#&& -> $ 209 | operation#|| -> $ 210 | operation#) -> $ 211 | compare_op#> -> > 212 | compare_op#>= -> >= 213 | compare_op#< -> < 214 | compare_op#<= -> <= 215 | compare_op#== -> == 216 | compare_op#!= -> != 217 | equal_op#= -> = 218 | equal_op#+= -> += 219 | equal_op#-= -> -= 220 | equal_op#*= -> *= 221 | equal_op#/= -> /= 222 | equal_op#%= -> %= 223 | value#( -> item value' 224 | value#IDN -> item value' 225 | value#FLOAT -> item value' 226 | value#CHAR -> item value' 227 | value#STR -> item value' 228 | value#INT10 -> item value' 229 | value#INT8 -> item value' 230 | value#INT16 -> item value' 231 | value'#+ -> + item value' 232 | value'#- -> - item value' 233 | value'#> -> $ 234 | value'#>= -> $ 235 | value'#< -> $ 236 | value'#<= -> $ 237 | value'#== -> $ 238 | value'#!= -> $ 239 | value'#= -> $ 240 | value'#+= -> $ 241 | value'#-= -> $ 242 | value'#*= -> $ 243 | value'#/= -> $ 244 | value'#%= -> $ 245 | value'#, -> $ 246 | value'#; -> $ 247 | value'#&& -> $ 248 | value'#|| -> $ 249 | value'#) -> $ 250 | item#( -> factor item' 251 | item#IDN -> factor item' 252 | item#FLOAT -> factor item' 253 | item#CHAR -> factor item' 254 | item#STR -> factor item' 255 | item#INT10 -> factor item' 256 | item#INT8 -> factor item' 257 | item#INT16 -> factor item' 258 | item'#* -> * factor item' 259 | item'#/ -> / factor item' 260 | item'#% -> % factor item' 261 | item'#+ -> $ 262 | item'#- -> $ 263 | item'#> -> $ 264 | item'#>= -> $ 265 | item'#< -> $ 266 | item'#<= -> $ 267 | item'#== -> $ 268 | item'#!= -> $ 269 | item'#= -> $ 270 | item'#+= -> $ 271 | item'#-= -> $ 272 | item'#*= -> $ 273 | item'#/= -> $ 274 | item'#%= -> $ 275 | item'#, -> $ 276 | item'#; -> $ 277 | item'#&& -> $ 278 | item'#|| -> $ 279 | item'#) -> $ 280 | factor#( -> ( value ) 281 | factor#IDN -> IDN call_func 282 | factor#FLOAT -> const 283 | factor#CHAR -> const 284 | factor#STR -> const 285 | factor#INT10 -> const 286 | factor#INT8 -> const 287 | factor#INT16 -> const 288 | call_func#( -> ( es ) 289 | call_func#* -> $ 290 | call_func#/ -> $ 291 | call_func#% -> $ 292 | call_func#+ -> $ 293 | call_func#- -> $ 294 | call_func#> -> $ 295 | call_func#>= -> $ 296 | call_func#< -> $ 297 | call_func#<= -> $ 298 | call_func#== -> $ 299 | call_func#!= -> $ 300 | call_func#= -> $ 301 | call_func#+= -> $ 302 | call_func#-= -> $ 303 | call_func#*= -> $ 304 | call_func#/= -> $ 305 | call_func#%= -> $ 306 | call_func#, -> $ 307 | call_func#; -> $ 308 | call_func#&& -> $ 309 | call_func#|| -> $ 310 | call_func#) -> $ 311 | es#( -> isnull_expr isnull_es 312 | es#IDN -> isnull_expr isnull_es 313 | es#FLOAT -> isnull_expr isnull_es 314 | es#CHAR -> isnull_expr isnull_es 315 | es#STR -> isnull_expr isnull_es 316 | es#INT10 -> isnull_expr isnull_es 317 | es#INT8 -> isnull_expr isnull_es 318 | es#INT16 -> isnull_expr isnull_es 319 | es#, -> isnull_expr isnull_es 320 | es#) -> isnull_expr isnull_es 321 | isnull_es#, -> , isnull_expr isnull_es 322 | isnull_es#) -> $ 323 | const#INT10 -> num_const 324 | const#INT8 -> num_const 325 | const#INT16 -> num_const 326 | const#FLOAT -> FLOAT 327 | const#CHAR -> CHAR 328 | const#STR -> STR 329 | num_const#INT10 -> INT10 330 | num_const#INT8 -> INT8 331 | num_const#INT16 -> INT16 332 | p#= -> = 333 | equal_op#+= -> += 334 | equal_op#-= -> -= 335 | equal_op#*= -> *= 336 | equal_op#/= -> /= 337 | equal_op#%= -> %= 338 | value#( -> item value' 339 | value#IDN -> item value' 340 | value#FLOAT -> item value' 341 | value#CHAR -> item value' 342 | value#STR -> item value' 343 | value#INT10 -> item value' 344 | value#INT8 -> item value' 345 | value#INT16 -> item value' 346 | value'#+ -> + item value' 347 | value'#- -> - item value' 348 | value'#> -> $ 349 | value'#>= -> $ 350 | value'#< -> $ 351 | value'#<= -> $ 352 | value'#== -> $ 353 | value'#!= -> $ 354 | value'#= -> $ 355 | value'#+= -> $ 356 | value'#-= -> $ 357 | value'#*= -> $ 358 | value'#/= -> $ 359 | value'#%= -> $ 360 | value'#, -> $ 361 | value'#; -> $ 362 | value'#int -> $ 363 | value'#short -> $ 364 | value'#long -> $ 365 | value'#char -> $ 366 | value'#float -> $ 367 | value'#double -> $ 368 | value'#void -> $ 369 | value'#unsigned -> $ 370 | value'#&& -> $ 371 | value'#|| -> $ 372 | value'#continue -> $ 373 | value'#break -> $ 374 | value'#return -> $ 375 | value'#while -> $ 376 | value'#for -> $ 377 | value'#do -> $ 378 | value'#if -> $ 379 | value'#switch -> $ 380 | value'#( -> $ 381 | value'#IDN -> $ 382 | value'#FLOAT -> $ 383 | value'#CHAR -> $ 384 | value'#STR -> $ 385 | value'#INT10 -> $ 386 | value'#INT8 -> $ 387 | value'#INT16 -> $ 388 | value'#) -> $ 389 | value'#{ -> $ 390 | item#( -> factor item' 391 | item#IDN -> factor item' 392 | item#FLOAT -> factor item' 393 | item#CHAR -> factor item' 394 | item#STR -> factor item' 395 | item#INT10 -> factor item' 396 | item#INT8 -> factor item' 397 | item#INT16 -> factor item' 398 | item'#* -> * factor item' 399 | item'#/ -> / factor item' 400 | item'#% -> % factor item' 401 | item'#+ -> $ 402 | item'#- -> $ 403 | factor#( -> ( value ) 404 | factor#IDN -> IDN call_func 405 | factor#FLOAT -> const 406 | factor#CHAR -> const 407 | factor#STR -> const 408 | factor#INT10 -> const 409 | factor#INT8 -> const 410 | factor#INT16 -> const 411 | call_func#( -> ( es ) 412 | call_func#* -> $ 413 | call_func#/ -> $ 414 | call_func#% -> $ 415 | es#( -> isnull_expr isnull_es 416 | es#IDN -> isnull_expr isnull_es 417 | es#FLOAT -> isnull_expr isnull_es 418 | es#CHAR -> isnull_expr isnull_es 419 | es#STR -> isnull_expr isnull_es 420 | es#INT10 -> isnull_expr isnull_es 421 | es#INT8 -> isnull_expr isnull_es 422 | es#INT16 -> isnull_expr isnull_es 423 | es#, -> isnull_expr isnull_es 424 | es#) -> isnull_expr isnull_es 425 | isnull_es#, -> , isnull_expr isnull_es 426 | isnull_es#) -> $ 427 | const#INT10 -> num_const 428 | const#INT8 -> num_const 429 | const#INT16 -> num_const 430 | const#FLOAT -> FLOAT 431 | const#CHAR -> CHAR 432 | const#STR -> STR 433 | num_const#INT10 -> INT10 434 | num_const#INT8 -> INT8 435 | num_const#INT16 -> INT16 436 | -------------------------------------------------------------------------------- /semantic/predictldy.txt: -------------------------------------------------------------------------------- 1 | S#int -> func funcs 2 | S#short -> func funcs 3 | S#long -> func funcs 4 | S#char -> func funcs 5 | S#float -> func funcs 6 | S#double -> func funcs 7 | S#void -> func funcs 8 | S#unsigned -> func funcs 9 | funcs#int -> func funcs 10 | funcs#short -> func funcs 11 | funcs#long -> func funcs 12 | funcs#char -> func funcs 13 | funcs#float -> func funcs 14 | funcs#double -> func funcs 15 | funcs#void -> func funcs 16 | funcs#unsigned -> func funcs 17 | func#int -> type IDN ( args ) func_body 18 | func#short -> type IDN ( args ) func_body 19 | func#long -> type IDN ( args ) func_body 20 | func#char -> type IDN ( args ) func_body 21 | func#float -> type IDN ( args ) func_body 22 | func#double -> type IDN ( args ) func_body 23 | func#void -> type IDN ( args ) func_body 24 | func#unsigned -> type IDN ( args ) func_body 25 | type#int -> int 26 | type#short -> short 27 | type#long -> long 28 | type#char -> char 29 | type#float -> float 30 | type#double -> double 31 | type#void -> void 32 | type#unsigned -> unsigned type 33 | args#int -> type IDN arg 34 | args#short -> type IDN arg 35 | args#long -> type IDN arg 36 | args#char -> type IDN arg 37 | args#float -> type IDN arg 38 | args#double -> type IDN arg 39 | args#void -> type IDN arg 40 | args#unsigned -> type IDN arg 41 | args#) -> $ 42 | arg#, -> , type IDN arg 43 | arg#) -> $ 44 | func_body#; -> ; 45 | func_body#{ -> block 46 | block#{ -> { define_stmts stmts } 47 | define_stmts#int -> define_stmt define_stmts 48 | define_stmts#short -> define_stmt define_stmts 49 | define_stmts#long -> define_stmt define_stmts 50 | define_stmts#char -> define_stmt define_stmts 51 | define_stmts#float -> define_stmt define_stmts 52 | define_stmts#double -> define_stmt define_stmts 53 | define_stmts#void -> define_stmt define_stmts 54 | define_stmts#unsigned -> define_stmt define_stmts 55 | define_stmts#continue -> $ 56 | define_stmts#break -> $ 57 | define_stmts#return -> $ 58 | define_stmts#while -> $ 59 | define_stmts#for -> $ 60 | define_stmts#do -> $ 61 | define_stmts#if -> $ 62 | define_stmts#switch -> $ 63 | define_stmts#( -> $ 64 | define_stmts#IDN -> $ 65 | define_stmts#FLOAT -> $ 66 | define_stmts#CHAR -> $ 67 | define_stmts#STR -> $ 68 | define_stmts#INT10 -> $ 69 | define_stmts#INT8 -> $ 70 | define_stmts#INT16 -> $ 71 | define_stmts#} -> $ 72 | define_stmt#int -> type IDN init vars ; 73 | define_stmt#short -> type IDN init vars ; 74 | define_stmt#long -> type IDN init vars ; 75 | define_stmt#char -> type IDN init vars ; 76 | define_stmt#float -> type IDN init vars ; 77 | define_stmt#double -> type IDN init vars ; 78 | define_stmt#void -> type IDN init vars ; 79 | define_stmt#unsigned -> type IDN init vars ; 80 | init#= -> = expression 81 | init#, -> $ 82 | init#; -> $ 83 | vars#, -> , IDN init vars 84 | vars#; -> $ 85 | stmts#continue -> stmt stmts 86 | stmts#break -> stmt stmts 87 | stmts#return -> stmt stmts 88 | stmts#while -> stmt stmts 89 | stmts#for -> stmt stmts 90 | stmts#do -> stmt stmts 91 | stmts#if -> stmt stmts 92 | stmts#switch -> stmt stmts 93 | stmts#( -> stmt stmts 94 | stmts#IDN -> stmt stmts 95 | stmts#FLOAT -> stmt stmts 96 | stmts#CHAR -> stmt stmts 97 | stmts#STR -> stmt stmts 98 | stmts#INT10 -> stmt stmts 99 | stmts#INT8 -> stmt stmts 100 | stmts#INT16 -> stmt stmts 101 | stmts#} -> $ 102 | stmts#case -> $ 103 | stmts#default -> $ 104 | stmt#( -> assign_stmt 105 | stmt#IDN -> assign_stmt 106 | stmt#FLOAT -> assign_stmt 107 | stmt#CHAR -> assign_stmt 108 | stmt#STR -> assign_stmt 109 | stmt#INT10 -> assign_stmt 110 | stmt#INT8 -> assign_stmt 111 | stmt#INT16 -> assign_stmt 112 | stmt#continue -> jump_stmt 113 | stmt#break -> jump_stmt 114 | stmt#return -> jump_stmt 115 | stmt#while -> iteration_stmt 116 | stmt#for -> iteration_stmt 117 | stmt#do -> iteration_stmt 118 | stmt#if -> branch_stmt 119 | stmt#switch -> branch_stmt 120 | assign_stmt#( -> expression ; 121 | assign_stmt#IDN -> expression ; 122 | assign_stmt#FLOAT -> expression ; 123 | assign_stmt#CHAR -> expression ; 124 | assign_stmt#STR -> expression ; 125 | assign_stmt#INT10 -> expression ; 126 | assign_stmt#INT8 -> expression ; 127 | assign_stmt#INT16 -> expression ; 128 | jump_stmt#continue -> continue ; 129 | jump_stmt#break -> break ; 130 | jump_stmt#return -> return isnull_expr ; 131 | iteration_stmt#while -> while ( logical_expression ) block_stmt 132 | iteration_stmt#for -> for ( isnull_expr ; isnull_expr ; isnull_expr ) block_stmt 133 | iteration_stmt#do -> do block_stmt while ( logical_expression ) ; 134 | branch_stmt#if -> if ( logical_expression ) block_stmt result 135 | result#else -> else block_stmt 136 | result#continue -> $ 137 | result#break -> $ 138 | result#return -> $ 139 | result#while -> $ 140 | result#for -> $ 141 | result#do -> $ 142 | result#if -> $ 143 | result#switch -> $ 144 | result#( -> $ 145 | result#IDN -> $ 146 | result#FLOAT -> $ 147 | result#CHAR -> $ 148 | result#STR -> $ 149 | result#INT10 -> $ 150 | result#INT8 -> $ 151 | result#INT16 -> $ 152 | result#} -> $ 153 | result#case -> $ 154 | result#default -> $ 155 | logical_expression#! -> ! expression bool_expression 156 | logical_expression#( -> expression bool_expression 157 | logical_expression#IDN -> expression bool_expression 158 | logical_expression#FLOAT -> expression bool_expression 159 | logical_expression#CHAR -> expression bool_expression 160 | logical_expression#STR -> expression bool_expression 161 | logical_expression#INT10 -> expression bool_expression 162 | logical_expression#INT8 -> expression bool_expression 163 | logical_expression#INT16 -> expression bool_expression 164 | bool_expression#&& -> lop expression bool_expression 165 | bool_expression#|| -> lop expression bool_expression 166 | bool_expression#) -> $ 167 | lop#&& -> && 168 | lop#|| -> || 169 | branch_stmt#switch -> switch ( IDN ) { case_stmt case_stmts default_stmt } 170 | case_stmts#case -> case_stmt case_stmts 171 | case_stmts#default -> $ 172 | case_stmt#case -> case const : stmts 173 | default_stmt#default -> default : stmts 174 | block_stmt#{ -> { stmts } 175 | isnull_expr#( -> expression 176 | isnull_expr#IDN -> expression 177 | isnull_expr#FLOAT -> expression 178 | isnull_expr#CHAR -> expression 179 | isnull_expr#STR -> expression 180 | isnull_expr#INT10 -> expression 181 | isnull_expr#INT8 -> expression 182 | isnull_expr#INT16 -> expression 183 | isnull_expr#; -> $ 184 | isnull_expr#) -> $ 185 | isnull_expr#, -> $ 186 | expression#( -> value operation 187 | expression#IDN -> value operation 188 | expression#FLOAT -> value operation 189 | expression#CHAR -> value operation 190 | expression#STR -> value operation 191 | expression#INT10 -> value operation 192 | expression#INT8 -> value operation 193 | expression#INT16 -> value operation 194 | operation#> -> compare_op value 195 | operation#>= -> compare_op value 196 | operation#< -> compare_op value 197 | operation#<= -> compare_op value 198 | operation#== -> compare_op value 199 | operation#!= -> compare_op value 200 | operation#= -> equal_op value 201 | operation#+= -> equal_op value 202 | operation#-= -> equal_op value 203 | operation#*= -> equal_op value 204 | operation#/= -> equal_op value 205 | operation#%= -> equal_op value 206 | operation#, -> $ 207 | operation#; -> $ 208 | operation#&& -> $ 209 | operation#|| -> $ 210 | operation#) -> $ 211 | compare_op#> -> > 212 | compare_op#>= -> >= 213 | compare_op#< -> < 214 | compare_op#<= -> <= 215 | compare_op#== -> == 216 | compare_op#!= -> != 217 | equal_op#= -> = 218 | equal_op#+= -> += 219 | equal_op#-= -> -= 220 | equal_op#*= -> *= 221 | equal_op#/= -> /= 222 | equal_op#%= -> %= 223 | value#( -> item value' 224 | value#IDN -> item value' 225 | value#FLOAT -> item value' 226 | value#CHAR -> item value' 227 | value#STR -> item value' 228 | value#INT10 -> item value' 229 | value#INT8 -> item value' 230 | value#INT16 -> item value' 231 | value'#+ -> + item value' 232 | value'#- -> - item value' 233 | value'#> -> $ 234 | value'#>= -> $ 235 | value'#< -> $ 236 | value'#<= -> $ 237 | value'#== -> $ 238 | value'#!= -> $ 239 | value'#= -> $ 240 | value'#+= -> $ 241 | value'#-= -> $ 242 | value'#*= -> $ 243 | value'#/= -> $ 244 | value'#%= -> $ 245 | value'#, -> $ 246 | value'#; -> $ 247 | value'#&& -> $ 248 | value'#|| -> $ 249 | value'#) -> $ 250 | item#( -> factor item' 251 | item#IDN -> factor item' 252 | item#FLOAT -> factor item' 253 | item#CHAR -> factor item' 254 | item#STR -> factor item' 255 | item#INT10 -> factor item' 256 | item#INT8 -> factor item' 257 | item#INT16 -> factor item' 258 | item'#* -> * factor item' 259 | item'#/ -> / factor item' 260 | item'#% -> % factor item' 261 | item'#+ -> $ 262 | item'#- -> $ 263 | item'#> -> $ 264 | item'#>= -> $ 265 | item'#< -> $ 266 | item'#<= -> $ 267 | item'#== -> $ 268 | item'#!= -> $ 269 | item'#= -> $ 270 | item'#+= -> $ 271 | item'#-= -> $ 272 | item'#*= -> $ 273 | item'#/= -> $ 274 | item'#%= -> $ 275 | item'#, -> $ 276 | item'#; -> $ 277 | item'#&& -> $ 278 | item'#|| -> $ 279 | item'#) -> $ 280 | factor#( -> ( value ) 281 | factor#IDN -> IDN call_func 282 | factor#FLOAT -> const 283 | factor#CHAR -> const 284 | factor#STR -> const 285 | factor#INT10 -> const 286 | factor#INT8 -> const 287 | factor#INT16 -> const 288 | call_func#( -> ( es ) 289 | call_func#* -> $ 290 | call_func#/ -> $ 291 | call_func#% -> $ 292 | call_func#+ -> $ 293 | call_func#- -> $ 294 | call_func#> -> $ 295 | call_func#>= -> $ 296 | call_func#< -> $ 297 | call_func#<= -> $ 298 | call_func#== -> $ 299 | call_func#!= -> $ 300 | call_func#= -> $ 301 | call_func#+= -> $ 302 | call_func#-= -> $ 303 | call_func#*= -> $ 304 | call_func#/= -> $ 305 | call_func#%= -> $ 306 | call_func#, -> $ 307 | call_func#; -> $ 308 | call_func#&& -> $ 309 | call_func#|| -> $ 310 | call_func#) -> $ 311 | es#( -> isnull_expr isnull_es 312 | es#IDN -> isnull_expr isnull_es 313 | es#FLOAT -> isnull_expr isnull_es 314 | es#CHAR -> isnull_expr isnull_es 315 | es#STR -> isnull_expr isnull_es 316 | es#INT10 -> isnull_expr isnull_es 317 | es#INT8 -> isnull_expr isnull_es 318 | es#INT16 -> isnull_expr isnull_es 319 | es#, -> isnull_expr isnull_es 320 | es#) -> isnull_expr isnull_es 321 | isnull_es#, -> , isnull_expr isnull_es 322 | isnull_es#) -> $ 323 | const#INT10 -> num_const 324 | const#INT8 -> num_const 325 | const#INT16 -> num_const 326 | const#FLOAT -> FLOAT 327 | const#CHAR -> CHAR 328 | const#STR -> STR 329 | num_const#INT10 -> INT10 330 | num_const#INT8 -> INT8 331 | num_const#INT16 -> INT16 332 | p#= -> = 333 | equal_op#+= -> += 334 | equal_op#-= -> -= 335 | equal_op#*= -> *= 336 | equal_op#/= -> /= 337 | equal_op#%= -> %= 338 | value#( -> item value' 339 | value#IDN -> item value' 340 | value#FLOAT -> item value' 341 | value#CHAR -> item value' 342 | value#STR -> item value' 343 | value#INT10 -> item value' 344 | value#INT8 -> item value' 345 | value#INT16 -> item value' 346 | value'#+ -> + item value' 347 | value'#- -> - item value' 348 | value'#> -> $ 349 | value'#>= -> $ 350 | value'#< -> $ 351 | value'#<= -> $ 352 | value'#== -> $ 353 | value'#!= -> $ 354 | value'#= -> $ 355 | value'#+= -> $ 356 | value'#-= -> $ 357 | value'#*= -> $ 358 | value'#/= -> $ 359 | value'#%= -> $ 360 | value'#, -> $ 361 | value'#; -> $ 362 | value'#int -> $ 363 | value'#short -> $ 364 | value'#long -> $ 365 | value'#char -> $ 366 | value'#float -> $ 367 | value'#double -> $ 368 | value'#void -> $ 369 | value'#unsigned -> $ 370 | value'#&& -> $ 371 | value'#|| -> $ 372 | value'#continue -> $ 373 | value'#break -> $ 374 | value'#return -> $ 375 | value'#while -> $ 376 | value'#for -> $ 377 | value'#do -> $ 378 | value'#if -> $ 379 | value'#switch -> $ 380 | value'#( -> $ 381 | value'#IDN -> $ 382 | value'#FLOAT -> $ 383 | value'#CHAR -> $ 384 | value'#STR -> $ 385 | value'#INT10 -> $ 386 | value'#INT8 -> $ 387 | value'#INT16 -> $ 388 | value'#) -> $ 389 | value'#{ -> $ 390 | item#( -> factor item' 391 | item#IDN -> factor item' 392 | item#FLOAT -> factor item' 393 | item#CHAR -> factor item' 394 | item#STR -> factor item' 395 | item#INT10 -> factor item' 396 | item#INT8 -> factor item' 397 | item#INT16 -> factor item' 398 | item'#* -> * factor item' 399 | item'#/ -> / factor item' 400 | item'#% -> % factor item' 401 | item'#+ -> $ 402 | item'#- -> $ 403 | factor#( -> ( value ) 404 | factor#IDN -> IDN call_func 405 | factor#FLOAT -> const 406 | factor#CHAR -> const 407 | factor#STR -> const 408 | factor#INT10 -> const 409 | factor#INT8 -> const 410 | factor#INT16 -> const 411 | call_func#( -> ( es ) 412 | call_func#* -> $ 413 | call_func#/ -> $ 414 | call_func#% -> $ 415 | es#( -> isnull_expr isnull_es 416 | es#IDN -> isnull_expr isnull_es 417 | es#FLOAT -> isnull_expr isnull_es 418 | es#CHAR -> isnull_expr isnull_es 419 | es#STR -> isnull_expr isnull_es 420 | es#INT10 -> isnull_expr isnull_es 421 | es#INT8 -> isnull_expr isnull_es 422 | es#INT16 -> isnull_expr isnull_es 423 | es#, -> isnull_expr isnull_es 424 | es#) -> isnull_expr isnull_es 425 | isnull_es#, -> , isnull_expr isnull_es 426 | isnull_es#) -> $ 427 | const#INT10 -> num_const 428 | const#INT8 -> num_const 429 | const#INT16 -> num_const 430 | const#FLOAT -> FLOAT 431 | const#CHAR -> CHAR 432 | const#STR -> STR 433 | num_const#INT10 -> INT10 434 | num_const#INT8 -> INT8 435 | num_const#INT16 -> INT16 436 | -------------------------------------------------------------------------------- /parsing/src/TextLex.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.HashMap; 3 | 4 | import javax.swing.table.DefaultTableModel; 5 | 6 | 7 | public class TextLex{ 8 | 9 | private String text; 10 | private DefaultTableModel tbmodel_lex_result; 11 | // private DefaultTableModel tbmodel_lex_error; 12 | private ArrayList lex_result_stack; 13 | private ArrayList> lex_error_stack; 14 | private int text_length; 15 | private int row_number=1; 16 | String[] Key = {"void", "int", "long", "double", "char", "float", "else", "if", "return", "for", "goto", "short", "static", "while", "do"}; 17 | 18 | public TextLex(String text, DefaultTableModel tb_lex_result, DefaultTableModel tb_lex_error){ 19 | lex_result_stack = new ArrayList(); 20 | lex_error_stack = new ArrayList>(); 21 | this.text = text; 22 | this.tbmodel_lex_result = tb_lex_result; 23 | // this.tbmodel_lex_error = tb_lex_error; 24 | text_length = text.length(); 25 | } 26 | 27 | public ArrayList get_Lex_Result(){ 28 | return lex_result_stack; 29 | } 30 | public ArrayList> get_Lex_Error() { 31 | // TODO Auto-generated constructor stub 32 | return lex_error_stack; 33 | } 34 | 35 | public int isAlpha(char c){ 36 | if(((c<='z')&&(c>='a')) || ((c<='Z')&&(c>='A')) || (c=='_')) 37 | return 1; 38 | else 39 | return 0; 40 | } 41 | 42 | public int isNumber(char c){ 43 | if((c>='0')&&(c<='9')) 44 | return 1; 45 | else 46 | return 0; 47 | } 48 | 49 | public int isKey(String t){ 50 | for(int i=0;i': 163 | return handleMore(i, s); 164 | case '<': 165 | return handleLess(i, s); 166 | case '%': 167 | ch = text.charAt(++i); 168 | if (ch=='=') { 169 | // 输出运算符 170 | s = s+ch; 171 | printResult(s, "运算符"); 172 | return ++i; 173 | } 174 | else if(ch=='s'||ch=='c'||ch=='d'||ch=='f'||ch=='l'){ 175 | // 输出类型标识符 176 | s = s+ch; 177 | printResult(s, "输出类型标识符"); 178 | return ++i; 179 | } 180 | else { 181 | // 输出求余标识符 182 | printResult(s, "求余标识符"); 183 | return i; 184 | } 185 | default: 186 | // 输出暂时无法识别的字符,制表符也被当成了有问题的字符 187 | printError(row_number, s, "暂时无法识别的标识符"); 188 | return ++i; 189 | } 190 | } 191 | } 192 | 193 | public int handleFirstAlpha(int arg, String arg0){ 194 | int i=arg; 195 | String s = arg0; 196 | char ch=text.charAt(++i); 197 | while(isAlpha(ch)==1 || isNumber(ch)==1){ 198 | s = s+ch; 199 | ch=text.charAt(++i); 200 | } 201 | // if(s.length()==1){ 202 | // printResult(s, "字符常数"); 203 | // return i; 204 | // } 205 | // 到了结尾 206 | if(isKey(s)==1){ 207 | // 输出key 208 | printResult(s, "关键字"); 209 | return i; 210 | 211 | } 212 | else { 213 | // 输出普通的标识符 214 | printResult(s, "标识符"); 215 | return i; 216 | } 217 | } 218 | 219 | public int handleFirstNum(int arg, String arg0){ 220 | int i = arg; 221 | char ch = text.charAt(++i); 222 | String s = arg0; 223 | while(isNumber(ch)==1){ 224 | s = s+ch; 225 | ch = text.charAt(++i); 226 | } 227 | if((text.charAt(i)==' ')||(text.charAt(i)=='\t')||(text.charAt(i)=='\n')||(text.charAt(i)=='\r')||(text.charAt(i)=='\0')||ch==';'||ch==','||ch==')'||ch==']'||ch=='['||ch=='('){ 228 | // 到了结尾,输出数字 229 | printResult(s, "整数"); 230 | return i; 231 | } 232 | else if (ch=='E') { 233 | if (text.charAt(i+1)=='+') { 234 | s = s+ch; 235 | ch = text.charAt(++i); 236 | s = s+ch; 237 | ch = text.charAt(++i); 238 | while (isNumber(ch)==1) { 239 | s = s+ch; 240 | ch = text.charAt(++i); 241 | } 242 | if(ch=='\r'||ch=='\n'||ch==';'||ch=='\t'){ 243 | printResult(s, "科学计数"); 244 | return ++i; 245 | } 246 | else { 247 | printError(i, s, "浮点数错误"); 248 | return i; 249 | } 250 | } 251 | else if (isNumber(text.charAt(i+1))==1) { 252 | s = s+ch; 253 | ch = text.charAt(++i); 254 | while (isNumber(ch)==1) { 255 | s = s+ch; 256 | ch = text.charAt(++i); 257 | } 258 | if(ch=='\r'||ch=='\n'||ch==';'||ch=='\t'){ 259 | printResult(s, "科学计数"); 260 | return ++i; 261 | } 262 | else { 263 | printError(row_number, s, "浮点数错误"); 264 | return i; 265 | } 266 | } 267 | else { 268 | printError(row_number, s, "科学计数法错误"); 269 | return ++i; 270 | } 271 | } 272 | 273 | // 浮点数判断 274 | else if (text.charAt(i)=='.'&&(isNumber(text.charAt(i+1))==1)) { 275 | s = s +'.'; 276 | ch = text.charAt(++i); 277 | while (isNumber(ch)==1) { 278 | s = s+ch; 279 | ch = text.charAt(++i); 280 | } 281 | if (ch=='E') { 282 | if (text.charAt(i+1)=='+') { 283 | s = s+ch; 284 | ch = text.charAt(++i); 285 | s = s+ch; 286 | ch = text.charAt(++i); 287 | while (isNumber(ch)==1) { 288 | s = s+ch; 289 | ch = text.charAt(++i); 290 | } 291 | if(ch=='\r'||ch=='\n'||ch==';'||ch=='\t'){ 292 | printResult(s, "科学计数"); 293 | return ++i; 294 | } 295 | else { 296 | printError(i, s, "浮点数错误"); 297 | return i; 298 | } 299 | } 300 | else if (isNumber(text.charAt(i+1))==1) { 301 | s = s+ch; 302 | ch = text.charAt(++i); 303 | while (isNumber(ch)==1) { 304 | s = s+ch; 305 | ch = text.charAt(++i); 306 | } 307 | if(ch=='\r'||ch=='\n'||ch==';'||ch=='\t'){ 308 | printResult(s, "科学计数"); 309 | return ++i; 310 | } 311 | else { 312 | printError(row_number, s, "浮点数错误"); 313 | return i; 314 | } 315 | } 316 | else { 317 | printError(row_number, s, "科学计数法错误"); 318 | return ++i; 319 | } 320 | } 321 | else if (ch=='\n'||ch=='\r'||ch=='\t'||ch==' '||ch=='\0'||ch!=','||ch!=';') { 322 | printResult(s, "浮点数"); 323 | return i; 324 | } 325 | else if (ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='\0') { 326 | printResult(s, "浮点数"); 327 | return i; 328 | } 329 | else { 330 | while (ch!='\n'&&ch!='\t'&&ch!=' '&&ch!='\r'&&ch!='\0'&&ch!=';'&&ch!='.'&&ch!=',') { 331 | s = s+ch; 332 | ch = text.charAt(++i); 333 | } 334 | printError(row_number, s, "不合法的字符"); 335 | return i; 336 | } 337 | } 338 | else if (ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='\0') { 339 | printResult(s, "整数"); 340 | return i; 341 | } 342 | else { 343 | do { 344 | ch = text.charAt(i++); 345 | s = s+ch; 346 | } while ((text.charAt(i)!=' ')&&(text.charAt(i)!='\t')&&(text.charAt(i)!='\n')&&(text.charAt(i)!='\r')&&(text.charAt(i)!='\0')); 347 | printError(row_number, s, "错误的标识符"); 348 | return i; 349 | } 350 | } 351 | public int handleChar(int arg, String arg0){ 352 | String s = arg0; 353 | int i = arg; 354 | char ch = text.charAt(++i); 355 | while(ch!='\''){ 356 | if (ch=='\r'||ch=='\n') { 357 | row_number++; 358 | } 359 | else if(ch=='\0'){ 360 | printError(row_number, s, "单字符错误"); 361 | return i; 362 | } 363 | s = s+ch; 364 | ch = text.charAt(++i); 365 | } 366 | s = s+ch; 367 | System.out.println(s); 368 | if (s.length()==3||s.equals("\'"+"\\"+"t"+"\'")||s.equals("\'"+"\\"+"n"+"\'")||s.equals("\'"+"\\"+"r"+"\'")) { 369 | printResult(s, "单字符"); 370 | } 371 | else 372 | printError(row_number, s, "字符溢出"); 373 | return ++i; 374 | } 375 | 376 | // 单行注释处理 377 | public int handleSingleLineNote(int arg, String arg0){ 378 | String s = arg0; 379 | int i = arg; 380 | char ch = text.charAt(++i); 381 | while (ch!='\r'&&ch!='\n'&&ch!='\0') { 382 | s = s+ch; 383 | ch = text.charAt(++i); 384 | } 385 | printResult(s, "单行注释"); 386 | return i; 387 | } 388 | 389 | // 字符串处理 390 | public int handleString(int arg, String arg0){ 391 | String s = arg0; 392 | int i=arg; 393 | char ch = text.charAt(++i); 394 | while(ch!='"'){ 395 | if (ch=='\r'||ch=='\n') { 396 | row_number++; 397 | } 398 | else if(ch=='\0'){ 399 | printError(row_number, s, "字符串没有闭合"); 400 | return i; 401 | } 402 | s = s+ch; 403 | ch = text.charAt(++i); 404 | } 405 | s = s+ch; 406 | printResult(s, "字符串"); 407 | return ++i; 408 | } 409 | 410 | public int handlePlus(int arg, String arg0){ 411 | int i=arg; 412 | char ch = text.charAt(++i); 413 | String s = arg0; 414 | if (ch=='+'){ 415 | // 输出运算符 416 | s = s+ch; 417 | printResult(s, "运算符"); 418 | return ++i; 419 | } 420 | 421 | else if(ch=='='){ 422 | s = s+ch; 423 | // 输出运算符 424 | printResult(s, "运算符"); 425 | return ++i; 426 | } 427 | else{ 428 | // 输出运算符 429 | printResult(s, "运算符"); 430 | return i; 431 | } 432 | } 433 | 434 | // 处理注释,没有考虑不闭合的情况 435 | public int handleNote(int arg, String arg0){ 436 | int i = arg; 437 | char ch=text.charAt(++i); 438 | String s = arg0+ch; 439 | ch = text.charAt(++i); 440 | while (ch!='*' || ((i+1)'){ 493 | s = s+ch; 494 | // 输出运算符 495 | printResult(s, "运算符"); 496 | return ++i; 497 | } 498 | else{ 499 | // 输出运算符 500 | printResult(s, "运算符"); 501 | return i; 502 | } 503 | } 504 | 505 | public int handleLess(int arg, String arg0){ 506 | int i=arg; 507 | String s = arg0; 508 | char ch = text.charAt(++i); 509 | if (ch=='='){ 510 | s = s+ch; 511 | // 输出运算符 512 | printResult(s, "运算符"); 513 | return ++i; 514 | } 515 | 516 | else if(ch=='<'){ 517 | s = s+ch; 518 | // 输出运算符 519 | printResult(s, "运算符"); 520 | return ++i; 521 | } 522 | else{ 523 | // 输出运算符 524 | printResult(s, "运算符"); 525 | return i; 526 | } 527 | } 528 | 529 | // 打印结果 530 | public void printResult(String rs_value, String rs_name){ 531 | // tbmodel_lex_result.addRow(new String[]{rs_value, rs_name}); 532 | if(rs_name.equals("标识符")){ 533 | lex_result_stack.add("IDN"); 534 | tbmodel_lex_result.addRow(new String[]{"IDN", rs_value}); 535 | } 536 | else if(rs_name.equals("整数")){ 537 | lex_result_stack.add("INT10"); 538 | tbmodel_lex_result.addRow(new String[]{"INT10", rs_value}); 539 | } 540 | else if (rs_name.equals("科学计数")||rs_name.equals("浮点数")) { 541 | lex_result_stack.add("FLOAT"); 542 | tbmodel_lex_result.addRow(new String[]{"FLOAT", rs_value}); 543 | } 544 | else if(rs_name.equals("单字符")){ 545 | lex_result_stack.add("CHAR"); 546 | tbmodel_lex_result.addRow(new String[]{"CHAR", rs_value}); 547 | } 548 | else if(rs_name.equals("字符串")){ 549 | lex_result_stack.add("STR"); 550 | tbmodel_lex_result.addRow(new String[]{"STR", rs_value}); 551 | } 552 | else { 553 | lex_result_stack.add(rs_value); 554 | tbmodel_lex_result.addRow(new String[]{rs_name, rs_value}); 555 | } 556 | 557 | } 558 | 559 | // 打印错误信息 560 | public void printError(int row_num, String rs_value, String rs_name) { 561 | // tbmodel_lex_error.addRow(new String[]{row_num+"", rs_value, rs_name}); 562 | HashMap hashMap = new HashMap(); 563 | hashMap.put("row_num", row_num+""); 564 | hashMap.put("rs_value", rs_value+""); 565 | hashMap.put("rs_name", rs_name+""); 566 | lex_error_stack.add(hashMap); 567 | tbmodel_lex_result.addRow(new String[]{"ERROR,"+rs_name, rs_value}); 568 | } 569 | 570 | } -------------------------------------------------------------------------------- /semantic/src/TextLex.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.HashMap; 3 | 4 | import javax.swing.table.DefaultTableModel; 5 | 6 | 7 | public class TextLex{ 8 | 9 | private String text; 10 | private DefaultTableModel tbmodel_lex_result; 11 | // private DefaultTableModel tbmodel_lex_error; 12 | private ArrayList lex_result_stack; 13 | private ArrayList> lex_error_stack; 14 | private int text_length; 15 | private int row_number=1; 16 | String[] Key = {"void", "int", "double", "long", "char", "float", "else", "if", "return", "for", "goto", "short", "static", "do", "while"}; 17 | 18 | public TextLex(String text, DefaultTableModel tb_lex_result, DefaultTableModel tb_lex_error){ 19 | lex_result_stack = new ArrayList(); 20 | lex_error_stack = new ArrayList>(); 21 | this.text = text; 22 | this.tbmodel_lex_result = tb_lex_result; 23 | // this.tbmodel_lex_error = tb_lex_error; 24 | text_length = text.length(); 25 | } 26 | 27 | public ArrayList get_Lex_Result(){ 28 | return lex_result_stack; 29 | } 30 | public ArrayList> get_Lex_Error() { 31 | // TODO Auto-generated constructor stub 32 | return lex_error_stack; 33 | } 34 | 35 | public int isAlpha(char c){ 36 | if(((c<='z')&&(c>='a')) || ((c<='Z')&&(c>='A')) || (c=='_')) 37 | return 1; 38 | else 39 | return 0; 40 | } 41 | 42 | public int isNumber(char c){ 43 | if((c>='0')&&(c<='9')) 44 | return 1; 45 | else 46 | return 0; 47 | } 48 | 49 | public int isKey(String t){ 50 | for(int i=0;i': 163 | return handleMore(i, s); 164 | case '<': 165 | return handleLess(i, s); 166 | case '%': 167 | ch = text.charAt(++i); 168 | if (ch=='=') { 169 | // 输出运算符 170 | s = s+ch; 171 | printResult(s, "运算符"); 172 | return ++i; 173 | } 174 | else if(ch=='s'||ch=='c'||ch=='d'||ch=='f'||ch=='l'){ 175 | // 输出类型标识符 176 | s = s+ch; 177 | printResult(s, "输出类型标识符"); 178 | return ++i; 179 | } 180 | else { 181 | // 输出求余标识符 182 | printResult(s, "求余标识符"); 183 | return i; 184 | } 185 | default: 186 | // 输出暂时无法识别的字符,制表符也被当成了有问题的字符 187 | printError(row_number, s, "暂时无法识别的标识符"); 188 | return ++i; 189 | } 190 | } 191 | } 192 | 193 | public int handleFirstAlpha(int arg, String arg0){ 194 | int i=arg; 195 | String s = arg0; 196 | char ch=text.charAt(++i); 197 | while(isAlpha(ch)==1 || isNumber(ch)==1){ 198 | s = s+ch; 199 | ch=text.charAt(++i); 200 | } 201 | // if(s.length()==1){ 202 | // printResult(s, "字符常数"); 203 | // return i; 204 | // } 205 | // 到了结尾 206 | if(isKey(s)==1){ 207 | // 输出key 208 | printResult(s, "关键字"); 209 | return i; 210 | 211 | } 212 | else { 213 | // 输出普通的标识符 214 | printResult(s, "标识符"); 215 | return i; 216 | } 217 | } 218 | 219 | public int handleFirstNum(int arg, String arg0){ 220 | int i = arg; 221 | char ch = text.charAt(++i); 222 | String s = arg0; 223 | while(isNumber(ch)==1){ 224 | s = s+ch; 225 | ch = text.charAt(++i); 226 | } 227 | if((text.charAt(i)==' ')||(text.charAt(i)=='\t')||(text.charAt(i)=='\n')||(text.charAt(i)=='\r')||(text.charAt(i)=='\0')||ch==';'||ch==','||ch==')'||ch==']'||ch=='['||ch=='('){ 228 | // 到了结尾,输出数字 229 | printResult(s, "整数"); 230 | return i; 231 | } 232 | else if (ch=='E') { 233 | if (text.charAt(i+1)=='+') { 234 | s = s+ch; 235 | ch = text.charAt(++i); 236 | s = s+ch; 237 | ch = text.charAt(++i); 238 | while (isNumber(ch)==1) { 239 | s = s+ch; 240 | ch = text.charAt(++i); 241 | } 242 | if(ch=='\r'||ch=='\n'||ch==';'||ch=='\t'){ 243 | printResult(s, "科学计数"); 244 | return ++i; 245 | } 246 | else { 247 | printError(i, s, "浮点数错误"); 248 | return i; 249 | } 250 | } 251 | else if (isNumber(text.charAt(i+1))==1) { 252 | s = s+ch; 253 | ch = text.charAt(++i); 254 | while (isNumber(ch)==1) { 255 | s = s+ch; 256 | ch = text.charAt(++i); 257 | } 258 | if(ch=='\r'||ch=='\n'||ch==';'||ch=='\t'){ 259 | printResult(s, "科学计数"); 260 | return ++i; 261 | } 262 | else { 263 | printError(row_number, s, "浮点数错误"); 264 | return i; 265 | } 266 | } 267 | else { 268 | printError(row_number, s, "科学计数法错误"); 269 | return ++i; 270 | } 271 | } 272 | 273 | // 浮点数判断 274 | else if (text.charAt(i)=='.'&&(isNumber(text.charAt(i+1))==1)) { 275 | s = s +'.'; 276 | ch = text.charAt(++i); 277 | while (isNumber(ch)==1) { 278 | s = s+ch; 279 | ch = text.charAt(++i); 280 | } 281 | if (ch=='E') { 282 | if (text.charAt(i+1)=='+') { 283 | s = s+ch; 284 | ch = text.charAt(++i); 285 | s = s+ch; 286 | ch = text.charAt(++i); 287 | while (isNumber(ch)==1) { 288 | s = s+ch; 289 | ch = text.charAt(++i); 290 | } 291 | if(ch=='\r'||ch=='\n'||ch==';'||ch=='\t'){ 292 | printResult(s, "科学计数"); 293 | return ++i; 294 | } 295 | else { 296 | printError(i, s, "浮点数错误"); 297 | return i; 298 | } 299 | } 300 | else if (isNumber(text.charAt(i+1))==1) { 301 | s = s+ch; 302 | ch = text.charAt(++i); 303 | while (isNumber(ch)==1) { 304 | s = s+ch; 305 | ch = text.charAt(++i); 306 | } 307 | if(ch=='\r'||ch=='\n'||ch==';'||ch=='\t'){ 308 | printResult(s, "科学计数"); 309 | return ++i; 310 | } 311 | else { 312 | printError(row_number, s, "浮点数错误"); 313 | return i; 314 | } 315 | } 316 | else { 317 | printError(row_number, s, "科学计数法错误"); 318 | return ++i; 319 | } 320 | } 321 | else if (ch=='\n'||ch=='\r'||ch=='\t'||ch==' '||ch=='\0'||ch!=','||ch!=';') { 322 | printResult(s, "浮点数"); 323 | return i; 324 | } 325 | else if (ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='\0') { 326 | printResult(s, "浮点数"); 327 | return i; 328 | } 329 | else { 330 | while (ch!='\n'&&ch!='\t'&&ch!=' '&&ch!='\r'&&ch!='\0'&&ch!=';'&&ch!='.'&&ch!=',') { 331 | s = s+ch; 332 | ch = text.charAt(++i); 333 | } 334 | printError(row_number, s, "不合法的字符"); 335 | return i; 336 | } 337 | } 338 | else if (ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='\0') { 339 | printResult(s, "整数"); 340 | return i; 341 | } 342 | else { 343 | do { 344 | ch = text.charAt(i++); 345 | s = s+ch; 346 | } while ((text.charAt(i)!=' ')&&(text.charAt(i)!='\t')&&(text.charAt(i)!='\n')&&(text.charAt(i)!='\r')&&(text.charAt(i)!='\0')); 347 | printError(row_number, s, "错误的标识符"); 348 | return i; 349 | } 350 | } 351 | public int handleChar(int arg, String arg0){ 352 | String s = arg0; 353 | int i = arg; 354 | char ch = text.charAt(++i); 355 | while(ch!='\''){ 356 | if (ch=='\r'||ch=='\n') { 357 | row_number++; 358 | } 359 | else if(ch=='\0'){ 360 | printError(row_number, s, "单字符错误"); 361 | return i; 362 | } 363 | s = s+ch; 364 | ch = text.charAt(++i); 365 | } 366 | s = s+ch; 367 | System.out.println(s); 368 | if (s.length()==3||s.equals("\'"+"\\"+"t"+"\'")||s.equals("\'"+"\\"+"n"+"\'")||s.equals("\'"+"\\"+"r"+"\'")) { 369 | printResult(s, "单字符"); 370 | } 371 | else 372 | printError(row_number, s, "字符溢出"); 373 | return ++i; 374 | } 375 | 376 | // 单行注释处理 377 | public int handleSingleLineNote(int arg, String arg0){ 378 | String s = arg0; 379 | int i = arg; 380 | char ch = text.charAt(++i); 381 | while (ch!='\r'&&ch!='\n'&&ch!='\0') { 382 | s = s+ch; 383 | ch = text.charAt(++i); 384 | } 385 | printResult(s, "单行注释"); 386 | return i; 387 | } 388 | 389 | // 字符串处理 390 | public int handleString(int arg, String arg0){ 391 | String s = arg0; 392 | int i=arg; 393 | char ch = text.charAt(++i); 394 | while(ch!='"'){ 395 | if (ch=='\r'||ch=='\n') { 396 | row_number++; 397 | } 398 | else if(ch=='\0'){ 399 | printError(row_number, s, "字符串没有闭合"); 400 | return i; 401 | } 402 | s = s+ch; 403 | ch = text.charAt(++i); 404 | } 405 | s = s+ch; 406 | printResult(s, "字符串"); 407 | return ++i; 408 | } 409 | 410 | public int handlePlus(int arg, String arg0){ 411 | int i=arg; 412 | char ch = text.charAt(++i); 413 | String s = arg0; 414 | if (ch=='+'){ 415 | // 输出运算符 416 | s = s+ch; 417 | printResult(s, "运算符"); 418 | return ++i; 419 | } 420 | 421 | else if(ch=='='){ 422 | s = s+ch; 423 | // 输出运算符 424 | printResult(s, "运算符"); 425 | return ++i; 426 | } 427 | else{ 428 | // 输出运算符 429 | printResult(s, "运算符"); 430 | return i; 431 | } 432 | } 433 | 434 | // 处理注释,没有考虑不闭合的情况 435 | public int handleNote(int arg, String arg0){ 436 | int i = arg; 437 | char ch=text.charAt(++i); 438 | String s = arg0+ch; 439 | ch = text.charAt(++i); 440 | while (ch!='*' || ((i+1)'){ 493 | s = s+ch; 494 | // 输出运算符 495 | printResult(s, "运算符"); 496 | return ++i; 497 | } 498 | else{ 499 | // 输出运算符 500 | printResult(s, "运算符"); 501 | return i; 502 | } 503 | } 504 | 505 | public int handleLess(int arg, String arg0){ 506 | int i=arg; 507 | String s = arg0; 508 | char ch = text.charAt(++i); 509 | if (ch=='='){ 510 | s = s+ch; 511 | // 输出运算符 512 | printResult(s, "运算符"); 513 | return ++i; 514 | } 515 | 516 | else if(ch=='<'){ 517 | s = s+ch; 518 | // 输出运算符 519 | printResult(s, "运算符"); 520 | return ++i; 521 | } 522 | else{ 523 | // 输出运算符 524 | printResult(s, "运算符"); 525 | return i; 526 | } 527 | } 528 | 529 | // 打印结果 530 | public void printResult(String rs_value, String rs_name){ 531 | // tbmodel_lex_result.addRow(new String[]{rs_value, rs_name}); 532 | if(rs_name.equals("标识符")){ 533 | lex_result_stack.add("IDN"); 534 | tbmodel_lex_result.addRow(new String[]{"IDN", rs_value}); 535 | } 536 | else if(rs_name.equals("整数")){ 537 | lex_result_stack.add("INT10"); 538 | tbmodel_lex_result.addRow(new String[]{"INT10", rs_value}); 539 | } 540 | else if (rs_name.equals("科学计数")||rs_name.equals("浮点数")) { 541 | lex_result_stack.add("FLOAT"); 542 | tbmodel_lex_result.addRow(new String[]{"FLOAT", rs_value}); 543 | } 544 | else if(rs_name.equals("单字符")){ 545 | lex_result_stack.add("CHAR"); 546 | tbmodel_lex_result.addRow(new String[]{"CHAR", rs_value}); 547 | } 548 | else if(rs_name.equals("字符串")){ 549 | lex_result_stack.add("STR"); 550 | tbmodel_lex_result.addRow(new String[]{"STR", rs_value}); 551 | } 552 | else { 553 | lex_result_stack.add(rs_value); 554 | tbmodel_lex_result.addRow(new String[]{rs_name, rs_value}); 555 | } 556 | 557 | } 558 | 559 | // 打印错误信息 560 | public void printError(int row_num, String rs_value, String rs_name) { 561 | // tbmodel_lex_error.addRow(new String[]{row_num+"", rs_value, rs_name}); 562 | HashMap hashMap = new HashMap(); 563 | hashMap.put("row_num", row_num+""); 564 | hashMap.put("rs_value", rs_value+""); 565 | hashMap.put("rs_name", rs_name+""); 566 | lex_error_stack.add(hashMap); 567 | tbmodel_lex_result.addRow(new String[]{"ERROR,"+rs_name, rs_value}); 568 | } 569 | 570 | } -------------------------------------------------------------------------------- /semantic/src/MyScanner.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | public class MyScanner { 5 | 6 | String[] keys={"asm", "auto", "break", "case", "cdecl", 7 | "char", "const", "continue", "default", "do", 8 | "double", "else", "enum", "extern", "far", 9 | "float", "for", "goto", "huge", "if", 10 | "interrupt", "int", "long", "near", "pascal", 11 | "register", "return", "short", "signed", "sizeof", 12 | "static", "struct", "switch", "typedef", "union", 13 | "unsigned", "void", "volatile", "while"}; 14 | String[] rwords={"new","delete"}; 15 | 16 | int pos=0;//用来扫描源程序的指针 17 | String source;//源程序 18 | String status="S"; 19 | 20 | public MyScanner(String source){ 21 | this.source=source; 22 | } 23 | 24 | public List execute(){ 25 | 26 | Token.freeId_list(); 27 | 28 | char next_char; 29 | int begin_pos=0; 30 | 31 | List list=new ArrayList(); 32 | 33 | while(true){ 34 | 35 | next_char=this.getNextChar(); 36 | 37 | // System.out.println(this.status+"\t"+next_char+"\tbegin_pos="+begin_pos+"\tpos="+pos); 38 | 39 | if(status.equals("S")){ 40 | if(next_char==0){ 41 | //什么也不做 42 | }else if(next_char=='0'){//AB 43 | this.status="AB"; 44 | }else if(next_char>='1' && next_char<='9'){//AC 45 | this.status="AC"; 46 | }else if(next_char=='\''){//BA 47 | this.status="BA"; 48 | }else if(next_char=='\"'){//CA 49 | this.status="CA"; 50 | }else if(next_char=='_' || (next_char>='a' && next_char<='z') || (next_char>='A' && next_char<='Z')){//DT 51 | this.status="DT"; 52 | }else if(next_char==' ' || next_char=='\t'){//E1 53 | begin_pos=this.pos; 54 | }else if(next_char=='\n' || next_char=='\r'){//E1 55 | list.add(new Token("ENTER",null)); 56 | begin_pos=this.pos; 57 | }else if(next_char=='('){//E2 58 | list.add(new Token("(","(")); 59 | begin_pos=this.pos; 60 | }else if(next_char==')'){//E2 61 | list.add(new Token(")",")")); 62 | begin_pos=this.pos; 63 | }else if(next_char=='['){//E2 64 | list.add(new Token("[","[")); 65 | begin_pos=this.pos; 66 | }else if(next_char==']'){//E2 67 | list.add(new Token("]","]")); 68 | begin_pos=this.pos; 69 | }else if(next_char=='.'){//E2 70 | list.add(new Token(".",".")); 71 | begin_pos=this.pos; 72 | }else if(next_char=='~'){//E2 73 | list.add(new Token("~","~")); 74 | begin_pos=this.pos; 75 | }else if(next_char=='?'){//E2 76 | list.add(new Token("?","?")); 77 | begin_pos=this.pos; 78 | }else if(next_char==':'){//E2 79 | list.add(new Token(":",":")); 80 | begin_pos=this.pos; 81 | }else if(next_char==','){//E2 82 | list.add(new Token(",",",")); 83 | begin_pos=this.pos; 84 | }else if(next_char=='{'){//E2 85 | list.add(new Token("{","{")); 86 | begin_pos=this.pos; 87 | }else if(next_char=='}'){//E2 88 | list.add(new Token("}","}")); 89 | begin_pos=this.pos; 90 | }else if(next_char==';'){//E2 91 | list.add(new Token(";",";")); 92 | begin_pos=this.pos; 93 | }else if(next_char=='-'){//EA 94 | this.status="EA"; 95 | }else if(next_char=='+'){//EB 96 | this.status="EB"; 97 | }else if(next_char=='<'){//EC 98 | this.status="EC"; 99 | }else if(next_char=='>'){//EE 100 | this.status="EE"; 101 | }else if(next_char=='='){//EG 102 | this.status="EG"; 103 | }else if(next_char=='&'){//EH 104 | this.status="EH"; 105 | }else if(next_char=='|'){//EI 106 | this.status="EI"; 107 | }else if(next_char=='*'){//EJ 108 | this.status="EJ"; 109 | }else if(next_char=='%'){//EL 110 | this.status="EL"; 111 | }else if(next_char=='^'){//EM 112 | this.status="EM"; 113 | }else if(next_char=='!'){//EN 114 | this.status="EN"; 115 | }else if(next_char=='/'){//FA 116 | this.status="FA"; 117 | }else{ 118 | list.add(new ErrorToken("ERROR","非法的开始字符",next_char+"")); 119 | begin_pos=this.pos; 120 | } 121 | 122 | }else if(status.equals("AB")){ 123 | if(next_char=='x' || next_char=='X'){//AE 124 | this.status="AE"; 125 | }else if(next_char>='0' && next_char<='7'){//AD 126 | this.status="AD"; 127 | }else if(next_char=='8' || next_char=='9'){//AI 128 | this.status="AI"; 129 | }else if(next_char=='.'){//AG 130 | this.status="AG"; 131 | }else if(next_char=='e' || next_char=='E'){//AJ 132 | this.status="AJ"; 133 | }else if(next_char=='u' || next_char=='U'){//AM 134 | list.add(new Token("unsigned",source.substring(begin_pos, pos))); 135 | begin_pos=this.pos; 136 | this.status="S"; 137 | }else if(next_char=='l' || next_char=='L'){//AN 138 | this.status="AN"; 139 | }else{ 140 | list.add(new Token(ConstantType.INT,source.substring(begin_pos, --pos))); 141 | begin_pos= pos; 142 | this.status="S"; 143 | } 144 | }else if(status.equals("AC")){ 145 | if(next_char>='0' && next_char<='9'){//AC 146 | continue; 147 | }else if(next_char=='.'){//AG 148 | this.status="AG"; 149 | }else if(next_char=='e' || next_char=='E'){//AJ 150 | this.status="AJ"; 151 | }else if(next_char=='u' || next_char=='U'){//AM 152 | list.add(new Token("unsigned",source.substring(begin_pos, pos))); 153 | begin_pos=this.pos; 154 | this.status="S"; 155 | }else if(next_char=='l' || next_char=='L'){//AN 156 | this.status="AN"; 157 | }else if(next_char==0){ 158 | list.add(new Token(ConstantType.INT,source.substring(begin_pos, --pos))); 159 | }else{ 160 | list.add(new Token(ConstantType.INT,source.substring(begin_pos, --pos))); 161 | begin_pos= pos; 162 | this.status="S"; 163 | } 164 | }else if(status.equals("AD")){ 165 | if(next_char>='0' && next_char<='7'){//AD 166 | continue; 167 | }else if(next_char=='8' || next_char=='9'){//AI 168 | this.status="AI"; 169 | }else if(next_char=='.'){//AG 170 | this.status="AG"; 171 | }else if(next_char=='e' || next_char=='E'){//AJ 172 | this.status="AJ"; 173 | }else if(next_char=='u' || next_char=='U'){//AM 174 | list.add(new Token("unsigned",source.substring(begin_pos, pos))); 175 | begin_pos=this.pos; 176 | this.status="S"; 177 | }else if(next_char=='l' || next_char=='L'){//AN 178 | this.status="AN"; 179 | }else if(next_char==0){ 180 | list.add(new Token(ConstantType.DOUBLE,source.substring(begin_pos, pos))); 181 | }else{ 182 | list.add(new Token(ConstantType.INT,source.substring(begin_pos, --pos))); 183 | begin_pos= pos; 184 | this.status="S"; 185 | } 186 | }else if(status.equals("AE")){ 187 | if((next_char>='0' && next_char<='9') || (next_char>='a' && next_char<='f') || (next_char>='A' && next_char<='F')){//AF 188 | this.status="AF"; 189 | }else{ 190 | list.add(new ErrorToken("ERROR","不完整的十六进制表示形式",source.substring(begin_pos, --pos))); 191 | begin_pos= pos; 192 | this.status="S"; 193 | } 194 | }else if(status.equals("AF")){ 195 | if((next_char>='0' && next_char<='9') || (next_char>='a' && next_char<='f') || (next_char>='A' && next_char<='F')){//AF 196 | continue; 197 | }else if(next_char=='u' || next_char=='U'){//AM 198 | list.add(new Token("unsigned",source.substring(begin_pos, pos))); 199 | begin_pos=this.pos; 200 | this.status="S"; 201 | }else if(next_char=='l' || next_char=='L'){//AN 202 | this.status="AN"; 203 | }else if(next_char==0){ 204 | list.add(new Token(ConstantType.DOUBLE,source.substring(begin_pos, --pos))); 205 | }else{ 206 | list.add(new Token(ConstantType.INT,source.substring(begin_pos, --pos))); 207 | begin_pos= pos; 208 | this.status="S"; 209 | } 210 | }else if(status.equals("AG")){ 211 | if(next_char>='0' && next_char<='9'){//AH 212 | this.status="AH"; 213 | }else{ 214 | list.add(new ErrorToken("ERROR","不完整的小数表示形式",source.substring(begin_pos, --pos))); 215 | begin_pos= pos; 216 | this.status="S"; 217 | } 218 | }else if(status.equals("AH")){ 219 | if(next_char>='0' && next_char<='9'){//AH 220 | continue; 221 | }else if(next_char=='e' || next_char=='E'){//AJ 222 | this.status="AJ"; 223 | }else if(next_char=='f' || next_char=='F'){//AQ 224 | list.add(new Token(ConstantType.FLOAT,source.substring(begin_pos, pos))); 225 | begin_pos=this.pos; 226 | this.status="S"; 227 | }else if(next_char=='l' || next_char=='L'){//AR 228 | list.add(new Token(ConstantType.LONG_DOUBLE,source.substring(begin_pos, pos))); 229 | begin_pos=this.pos; 230 | this.status="S"; 231 | }else if(next_char==0){ 232 | list.add(new Token(ConstantType.DOUBLE,source.substring(begin_pos, pos))); 233 | }else{ 234 | list.add(new Token(ConstantType.DOUBLE,source.substring(begin_pos, --pos))); 235 | begin_pos= pos; 236 | this.status="S"; 237 | } 238 | }else if(status.equals("AI")){ 239 | if(next_char>='0' && next_char<='9'){//AI 240 | continue; 241 | }else if(next_char=='.'){//AG 242 | this.status="AG"; 243 | }else if(next_char=='e' || next_char=='E'){//AJ 244 | this.status="AJ"; 245 | }else{ 246 | list.add(new ErrorToken("ERROR","非法的八进制数表示形式",source.substring(begin_pos, --pos))); 247 | begin_pos= pos; 248 | this.status="S"; 249 | } 250 | }else if(status.equals("AJ")){ 251 | if(next_char=='+' || next_char=='-'){//AK 252 | this.status="AK"; 253 | }else if(next_char>='0' && next_char<='9'){//AL 254 | this.status="AL"; 255 | }else{ 256 | list.add(new ErrorToken("ERROR","不完整的指数表示形式",source.substring(begin_pos, --pos))); 257 | begin_pos= pos; 258 | this.status="S"; 259 | } 260 | }else if(status.equals("AK")){ 261 | if(next_char>='0' && next_char<='9'){//AL 262 | this.status="AL"; 263 | }else{ 264 | list.add(new ErrorToken("ERROR","不完整的指数表示形式",source.substring(begin_pos, --pos))); 265 | begin_pos= pos; 266 | this.status="S"; 267 | } 268 | }else if(status.equals("AL")){ 269 | if(next_char>='0' && next_char<='9'){//AL 270 | continue; 271 | }else if(next_char=='f' || next_char=='F'){//AQ 272 | list.add(new Token(ConstantType.FLOAT,source.substring(begin_pos, pos))); 273 | begin_pos=this.pos; 274 | this.status="S"; 275 | }else if(next_char=='l' || next_char=='L'){//AR 276 | list.add(new Token(ConstantType.LONG_DOUBLE,source.substring(begin_pos, pos))); 277 | begin_pos=this.pos; 278 | this.status="S"; 279 | }else{ 280 | list.add(new Token(ConstantType.DOUBLE,source.substring(begin_pos, --pos))); 281 | begin_pos=this.pos; 282 | this.status="S"; 283 | } 284 | }else if(status.equals("AN")){ 285 | if(next_char=='u' || next_char=='U'){//AP 286 | list.add(new Token(ConstantType.LONG_UNSIGNED,source.substring(begin_pos, pos))); 287 | begin_pos=this.pos; 288 | this.status="S"; 289 | }else{ 290 | list.add(new Token(ConstantType.LONG,source.substring(begin_pos, --pos))); 291 | begin_pos=this.pos; 292 | this.status="S"; 293 | } 294 | 295 | }else if(status.equals("BA")){ 296 | if(next_char=='\\'){//BD 297 | this.status="BD"; 298 | }else if(next_char=='\'' || next_char=='\n' || next_char=='\r'){ 299 | list.add(new ErrorToken("ERROR","不完整的字符表示形式",source.substring(begin_pos, --pos))); 300 | begin_pos= pos; 301 | this.status="S"; 302 | }else if(next_char==0){ 303 | list.add(new ErrorToken("ERROR","不完整的字符表示形式",source.substring(begin_pos, --pos))); 304 | }else{//BB 305 | this.status="BB"; 306 | } 307 | }else if(status.equals("BB")){ 308 | if(next_char=='\''){//BC 309 | list.add(new Token(ConstantType.CHAR,source.substring(begin_pos, pos))); 310 | begin_pos=this.pos; 311 | this.status="S"; 312 | }else{ 313 | list.add(new ErrorToken("ERROR","错误的字符表示形式",source.substring(begin_pos, --pos))); 314 | begin_pos= pos; 315 | this.status="S"; 316 | } 317 | }else if(status.equals("BD")){ 318 | if(next_char=='0' || next_char=='1'){//BI 319 | this.status="BI"; 320 | }else if(next_char>='2' && next_char<='7'){//BJ 321 | this.status="BJ"; 322 | }else if(next_char=='x'){//BM 323 | this.status="BM"; 324 | }else if(next_char=='\n' || next_char=='\r'){ 325 | list.add(new ErrorToken("ERROR","不完整的字符表示形式",source.substring(begin_pos, --pos))); 326 | begin_pos= pos; 327 | this.status="S"; 328 | }else if(next_char==0){ 329 | list.add(new ErrorToken("ERROR","不完整的字符表示形式",source.substring(begin_pos, --pos))); 330 | }else{//BEG 331 | this.status="BEG"; 332 | } 333 | }else if(status.equals("BEG")){ 334 | if(next_char=='\''){//BFH 335 | list.add(new Token(ConstantType.CHAR,source.substring(begin_pos, pos))); 336 | begin_pos=this.pos; 337 | this.status="S"; 338 | }else{ 339 | list.add(new ErrorToken("ERROR","错误的字符表示形式",source.substring(begin_pos, --pos))); 340 | begin_pos= pos; 341 | this.status="S"; 342 | } 343 | }else if(status.equals("BI")){ 344 | if(next_char=='\''){//BL 345 | list.add(new Token(ConstantType.CHAR,source.substring(begin_pos, pos))); 346 | begin_pos=this.pos; 347 | this.status="S"; 348 | }else if(next_char>='0' && next_char<='7'){//BJ 349 | this.status="BJ"; 350 | }else{ 351 | list.add(new ErrorToken("ERROR","不完整的字符表示形式",source.substring(begin_pos, --pos))); 352 | begin_pos= pos; 353 | this.status="S"; 354 | } 355 | }else if(status.equals("BJ")){ 356 | if(next_char=='\''){//BL 357 | list.add(new Token(ConstantType.CHAR,source.substring(begin_pos, pos))); 358 | begin_pos=this.pos; 359 | this.status="S"; 360 | }else if(next_char>='0' && next_char<='7'){//BK 361 | this.status="BK"; 362 | }else{ 363 | list.add(new ErrorToken("ERROR","不完整的字符表示形式",source.substring(begin_pos, --pos))); 364 | begin_pos= pos; 365 | this.status="S"; 366 | } 367 | }else if(status.equals("BK")){ 368 | if(next_char=='\''){//BL 369 | list.add(new Token(ConstantType.CHAR,source.substring(begin_pos, pos))); 370 | begin_pos=this.pos; 371 | this.status="S"; 372 | }else{ 373 | list.add(new ErrorToken("ERROR","不完整的字符表示形式",source.substring(begin_pos, --pos))); 374 | begin_pos= pos; 375 | this.status="S"; 376 | } 377 | }else if(status.equals("BM")){ 378 | if(next_char>='0' && next_char<='7'){//BN 379 | this.status="BN"; 380 | }else if((next_char>='8' && next_char<='9') || (next_char>='a' && next_char<='f') || (next_char>='A' && next_char<='F')){//BP 381 | this.status="BP"; 382 | }else{ 383 | list.add(new ErrorToken("ERROR","不完整的字符表示形式",source.substring(begin_pos, --pos))); 384 | begin_pos= pos; 385 | this.status="S"; 386 | } 387 | }else if(status.equals("BN")){ 388 | if(next_char=='\''){//BQ 389 | list.add(new Token(ConstantType.CHAR,source.substring(begin_pos, pos))); 390 | begin_pos=this.pos; 391 | this.status="S"; 392 | }else if((next_char>='0' && next_char<='9') || (next_char>='a' && next_char<='f') || (next_char>='A' && next_char<='F')){//BP 393 | this.status="BP"; 394 | }else{ 395 | list.add(new ErrorToken("ERROR","不完整的字符表示形式",source.substring(begin_pos, --pos))); 396 | begin_pos= pos; 397 | this.status="S"; 398 | } 399 | }else if(status.equals("BP")){ 400 | if(next_char=='\''){//BQ 401 | list.add(new Token(ConstantType.CHAR,source.substring(begin_pos, pos))); 402 | begin_pos=this.pos; 403 | this.status="S"; 404 | }else{ 405 | list.add(new ErrorToken("ERROR","不完整的字符表示形式",source.substring(begin_pos, --pos))); 406 | begin_pos= pos; 407 | this.status="S"; 408 | } 409 | }else if(status.equals("CA")){ 410 | if(next_char=='\"'){//CT 411 | list.add(new Token(ConstantType.STRING,source.substring(begin_pos, pos))); 412 | begin_pos=this.pos; 413 | this.status="S"; 414 | }else if(next_char=='\\'){//CB 415 | this.status="CB"; 416 | }else if(next_char=='\n' || next_char=='\r'){ 417 | list.add(new ErrorToken("ERROR","不完整的字符串表示形式",source.substring(begin_pos, --pos))); 418 | begin_pos= pos; 419 | this.status="S"; 420 | }else if(next_char==0){ 421 | list.add(new ErrorToken("ERROR","不完整的字符串表示形式",source.substring(begin_pos, --pos))); 422 | }else{//CA 423 | continue; 424 | } 425 | }else if(status.equals("CB")){ 426 | if(next_char=='\n' || next_char=='\r'){ 427 | list.add(new ErrorToken("ERROR","不完整的字符串表示形式",source.substring(begin_pos, --pos))); 428 | begin_pos= pos; 429 | this.status="S"; 430 | }else{//CA 431 | this.status="CA"; 432 | } 433 | }else if(status.equals("DT")){ 434 | if(next_char=='_' || (next_char>='a' && next_char<='z') || (next_char>='A' && next_char<='Z') || (next_char>='0' && next_char<='9')){//DT 435 | continue; 436 | }else{ 437 | String temp=source.substring(begin_pos, --pos); 438 | 439 | boolean flag=true; 440 | for(int i=0;i'){//E3 463 | list.add(new Token("->",source.substring(begin_pos, pos))); 464 | begin_pos=this.pos; 465 | this.status="S"; 466 | }else if(next_char=='='){//E4 467 | list.add(new Token("-=",source.substring(begin_pos, pos))); 468 | begin_pos=this.pos; 469 | this.status="S"; 470 | }else if(next_char=='-'){//E5 471 | list.add(new Token("--",source.substring(begin_pos, pos))); 472 | begin_pos=this.pos; 473 | this.status="S"; 474 | }else{ 475 | list.add(new Token("-",source.substring(begin_pos, --pos))); 476 | begin_pos=this.pos; 477 | this.status="S"; 478 | } 479 | }else if(status.equals("EB")){ 480 | if(next_char=='+'){//E6 481 | list.add(new Token("++",source.substring(begin_pos, pos))); 482 | begin_pos=this.pos; 483 | this.status="S"; 484 | }else if(next_char=='='){//E7 485 | list.add(new Token("+=",source.substring(begin_pos, pos))); 486 | begin_pos=this.pos; 487 | this.status="S"; 488 | }else{ 489 | list.add(new Token("+",source.substring(begin_pos, --pos))); 490 | begin_pos=this.pos; 491 | this.status="S"; 492 | } 493 | }else if(status.equals("EC")){ 494 | if(next_char=='<'){//ED 495 | this.status="ED"; 496 | }else if(next_char=='='){//E81 497 | list.add(new Token("<=",source.substring(begin_pos, pos))); 498 | begin_pos=this.pos; 499 | this.status="S"; 500 | }else{ 501 | list.add(new Token("<",source.substring(begin_pos, --pos))); 502 | begin_pos=this.pos; 503 | this.status="S"; 504 | } 505 | }else if(status.equals("ED")){ 506 | if(next_char=='='){//E8 507 | list.add(new Token("<<=",source.substring(begin_pos, pos))); 508 | begin_pos=this.pos; 509 | this.status="S"; 510 | }else{ 511 | list.add(new Token("<<",source.substring(begin_pos, --pos))); 512 | begin_pos=this.pos; 513 | this.status="S"; 514 | } 515 | }else if(status.equals("EE")){ 516 | if(next_char=='>'){//EF 517 | this.status="EF"; 518 | }else if(next_char=='='){//E10 519 | list.add(new Token(">=",source.substring(begin_pos, pos))); 520 | begin_pos=this.pos; 521 | this.status="S"; 522 | }else{ 523 | list.add(new Token(">",source.substring(begin_pos, --pos))); 524 | begin_pos=this.pos; 525 | this.status="S"; 526 | } 527 | }else if(status.equals("EF")){ 528 | if(next_char=='='){//E9 529 | list.add(new Token(">>=",source.substring(begin_pos, pos))); 530 | begin_pos=this.pos; 531 | this.status="S"; 532 | }else{ 533 | list.add(new Token(">>",source.substring(begin_pos, --pos))); 534 | begin_pos=this.pos; 535 | this.status="S"; 536 | } 537 | }else if(status.equals("EG")){ 538 | if(next_char=='='){//E11 539 | list.add(new Token("==",source.substring(begin_pos, pos))); 540 | begin_pos=this.pos; 541 | this.status="S"; 542 | }else{ 543 | list.add(new Token("=",source.substring(begin_pos, --pos))); 544 | begin_pos=this.pos; 545 | this.status="S"; 546 | } 547 | }else if(status.equals("EH")){ 548 | if(next_char=='&'){//E12 549 | list.add(new Token("&&",source.substring(begin_pos, pos))); 550 | begin_pos=this.pos; 551 | this.status="S"; 552 | }else if(next_char=='='){//E13 553 | list.add(new Token("&=",source.substring(begin_pos, pos))); 554 | begin_pos=this.pos; 555 | this.status="S"; 556 | }else{ 557 | list.add(new Token("&",source.substring(begin_pos, --pos))); 558 | begin_pos=this.pos; 559 | this.status="S"; 560 | } 561 | }else if(status.equals("EI")){ 562 | if(next_char=='|'){//E14 563 | list.add(new Token("||",source.substring(begin_pos, pos))); 564 | begin_pos=this.pos; 565 | this.status="S"; 566 | }else if(next_char=='='){//E15 567 | list.add(new Token("|=",source.substring(begin_pos, pos))); 568 | begin_pos=this.pos; 569 | this.status="S"; 570 | }else{ 571 | list.add(new Token("|",source.substring(begin_pos, --pos))); 572 | begin_pos=this.pos; 573 | this.status="S"; 574 | } 575 | }else if(status.equals("EJ")){ 576 | if(next_char=='='){//E16 577 | list.add(new Token("*=",source.substring(begin_pos, pos))); 578 | begin_pos=this.pos; 579 | this.status="S"; 580 | }else{ 581 | list.add(new Token("*",source.substring(begin_pos, --pos))); 582 | begin_pos=this.pos; 583 | this.status="S"; 584 | } 585 | }else if(status.equals("EL")){ 586 | if(next_char=='='){//E17 587 | list.add(new Token("%=",source.substring(begin_pos, pos))); 588 | begin_pos=this.pos; 589 | this.status="S"; 590 | }else{ 591 | list.add(new Token("%",source.substring(begin_pos, --pos))); 592 | begin_pos=this.pos; 593 | this.status="S"; 594 | } 595 | }else if(status.equals("EM")){ 596 | if(next_char=='='){//E18 597 | list.add(new Token("^=",source.substring(begin_pos, pos))); 598 | begin_pos=this.pos; 599 | this.status="S"; 600 | }else{ 601 | list.add(new Token("^",source.substring(begin_pos, --pos))); 602 | begin_pos=this.pos; 603 | this.status="S"; 604 | } 605 | }else if(status.equals("EN")){ 606 | if(next_char=='='){//E19 607 | list.add(new Token("!=",source.substring(begin_pos, pos))); 608 | begin_pos=this.pos; 609 | this.status="S"; 610 | }else{ 611 | list.add(new Token("!",source.substring(begin_pos, --pos))); 612 | begin_pos=this.pos; 613 | this.status="S"; 614 | } 615 | }else if(status.equals("FA")){ 616 | if(next_char=='/'){//FC 617 | this.status="FC"; 618 | }else if(next_char=='*'){//FE 619 | this.status="FE"; 620 | }else if(next_char=='='){//FB 621 | list.add(new Token("/=",source.substring(begin_pos, pos))); 622 | begin_pos=this.pos; 623 | this.status="S"; 624 | }else{ 625 | list.add(new Token("/",source.substring(begin_pos, --pos))); 626 | begin_pos=this.pos; 627 | this.status="S"; 628 | } 629 | }else if(status.equals("FC")){ 630 | if(next_char=='\n' || next_char=='\r'){ 631 | begin_pos=this.pos; 632 | this.status="S"; 633 | list.add(new Token("ENTER",null)); 634 | }else if(next_char==0){ 635 | break; 636 | }else{ 637 | continue; 638 | } 639 | }else if(status.equals("FE")){ 640 | if(next_char=='*'){ 641 | this.status="FF"; 642 | }else if(next_char==0){ 643 | list.add(new ErrorToken("ERROR","缺少\'*/\'作为注释的结束符",source.substring(begin_pos, --pos))); 644 | }else{ 645 | continue; 646 | } 647 | }else if(status.equals("FF")){ 648 | if(next_char=='/'){ 649 | begin_pos=this.pos; 650 | this.status="S"; 651 | }else if(next_char==0){ 652 | list.add(new ErrorToken("ERROR","缺少\'*/\'作为注释的结束符",source.substring(begin_pos, --pos))); 653 | }else if(next_char=='*'){ 654 | continue; 655 | }else{ 656 | this.status="FE"; 657 | } 658 | } 659 | if(next_char==0) 660 | break; 661 | } 662 | 663 | return list; 664 | } 665 | 666 | private char getNextChar(){ 667 | if(pos>=source.length()){ 668 | pos++; 669 | return 0; 670 | }else{ 671 | return source.charAt(pos++); 672 | } 673 | } 674 | } 675 | --------------------------------------------------------------------------------