input.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <link rel="stylesheet" type="text/css" href="style.css"> <title>Input</title> </head> <body> <h1>简单词法分析器</h1> <p>输入源程序:</p> <textarea id="input" rows="10" cols="50"></textarea> <br> <button id="analysis" type="button" οnclick="analysis()">分析</button> <script type="text/javascript" src="analyzer.js"></script> <pre id="output"> </pre> </body> </html>
analyzer.js
var state = 0; var str = ""; var result = ""; var countdot = 0; var counte = 0; var line = 1; //判断字母 function isChar(ch) { return (ch<='z')&&(ch>='a')||(ch<='Z')&&(ch>='A')&&(ch!='e'); } //判断数字 function isDigit(ch){ return (ch>='0')&&(ch<='9'); } //判断运算符 function isOperator(ch) { return ch=="+"||ch=="-"||ch=="*"||ch=="/"||ch=="%"||ch=="="||ch=="<"||ch=="<"; } //判断界符 function isDelimiter(ch){ return ch==","||ch==";"||ch=="("||ch==")"||ch=="/*"||ch=="*/"||ch=="{"||ch=="}"; } //判断空格 function isSpace(ch){ return ch==' '; } //判断关键字 function isKey(str) { return str=="int"||str == "for"||str == "if"||str == "else"||str == "while"||str == "do"||str == "float"|| str == "switch"||str == "case"||str == "default"||str=="char"||str=="void"; } //判断下划线 function isUnderline(ch) { return ch=="_"; } //判断美元符号 function isDollar(ch) { return ch=="$"; } //判断小数点 function isdotted(ch) { return ch=="."; } //判断科学计数法 function ise(ch) { return ch=="e"; } //判断换行 function isEnter(ch) { return ch=="\n"; } /* * 0:状态初始化 * 1:关键字 * 2:变量 * 3:数字 * 4:字符串 * 5:运算符 * 6:界符 * */ function analysis(){ line = 1; result = ""; countdot = 0; counte = 0; var s = document.getElementById("input").value; for(var i=0;i<s.length;i++) { //console.log(s.charAt(i)); var ch = s.charAt(i); switch (state){ case 0: if(isChar(ch)||isDollar(ch)||isUnderline(ch)){ str = "" + ch; state = 1; } else if(isDigit(ch)){ str = "" + ch; state = 3; } else if(ch == '\"'){ str = ""; state = 4; } else if(isOperator(ch)){ str = "" + ch; state = 5; //console.log("<operator:"+ch+">"); result = result + "<operator:"+ch+">" + "\n"; state = 0; } else if(isDelimiter(ch)){ str = "" + ch; state = 6; //console.log("<delimiter:"+ch+">"); result = result + "<delimiter:"+ch+">" + "\n"; state = 0; } else if(isEnter(ch)){ line++; } break; case 1: if(isChar(ch)||isDigit(ch)||isUnderline(ch)){ str = str +ch; }else if(isDelimiter(ch)||isOperator(ch)||isSpace(ch)){ if(isKey(str)){ result = result + "<key:"+str+">" + "\n"; }else{ result = result + "<var:"+str+">" + "\n"; } i--; state = 0; }else{ result = result + "<error:"+str+"> " + line + "\n"; i--; state = 0; } break; case 3: if(isDigit(ch)){ str = str + ch; }else if(isdotted(ch)){ countdot++; if(countdot<2) str = str + ch; else result = result + "error " + line ; }else if(ise(ch)){ counte++; if(counte<2) str = str + ch; else result = result + "error " + line ; } else if(isDelimiter(ch)||isOperator(ch)||isSpace(ch)){ result = result + "<number:"+str+">" + "\n"; i--; state = 0; }else{ result = result + "<error:"+str+"> " + line + "\n"; i--; state = 0; } break; case 4: if(ch == '\"'){ //console.log("<string:"+str+">"); result = result + "<string:"+str+">" + "\n"; state = 0; }else{ str = str + ch; } break; } } var o = document.getElementById("output"); o.lastChild.nodeValue = result; }
style.css
body{ font-family: sans-serif; } h1{ color:#699; } #output{ color: blue; font-family: sans-serif; font-size: 16px; } #input{ color: red; font-family: sans-serif; font-size: 16px; }