📄 sbasic.java
字号:
int var;
double val = 0.0;
String str;
BufferedReader br = new
BufferedReader(new InputStreamReader(System.in));
getToken(); // see if prompt string is present
if(tokType == QUOTEDSTR) {
// if so, print it and check for comma
System.out.print(token);
getToken();
if(!token.equals(",")) handleErr(SYNTAX);
getToken();
}
else System.out.print("? "); // otherwise, prompt with ?
// get the input var
var = Character.toUpperCase(token.charAt(0)) - 'A';
try {
str = br.readLine();
val = Double.parseDouble(str); // read the value
} catch (IOException exc) {
handleErr(INPUTIOERROR);
} catch (NumberFormatException exc) {
/* You might want to handle this error
differently than the other interpreter
errors. */
System.out.println("Invalid input.");
}
vars[var] = val; // store it
}
// Execute a GOSUB.
private void gosub() throws InterpreterException
{
Integer loc;
getToken();
// Find the label to call.
loc = (Integer) labelTable.get(token);
if(loc == null)
handleErr(UNDEFLABEL); // label not defined
else {
// Save place to return to.
gStack.push(new Integer(progIdx));
// Start program running at that loc.
progIdx = loc.intValue();
}
}
// Return from GOSUB.
private void greturn() throws InterpreterException
{
Integer t;
try {
// Restore program index.
t = (Integer) gStack.pop();
progIdx = t.intValue();
} catch(EmptyStackException exc) {
handleErr(RETURNWITHOUTGOSUB);
}
}
// **************** Expression Parser ****************
// Parser entry point.
private double evaluate() throws InterpreterException
{
double result = 0.0;
getToken();
if(token.equals(EOP))
handleErr(NOEXP); // no expression present
// Parse and evaluate the expression.
result = evalExp1();
putBack();
return result;
}
// Process relational operators.
private double evalExp1() throws InterpreterException
{
double l_temp, r_temp, result;
char op;
result = evalExp2();
// If at end of program, return.
if(token.equals(EOP)) return result;
op = token.charAt(0);
if(isRelop(op)) {
l_temp = result;
getToken();
r_temp = evalExp1();
switch(op) { // perform the relational operation
case '<':
if(l_temp < r_temp) result = 1.0;
else result = 0.0;
break;
case LE:
if(l_temp <= r_temp) result = 1.0;
else result = 0.0;
break;
case '>':
if(l_temp > r_temp) result = 1.0;
else result = 0.0;
break;
case GE:
if(l_temp >= r_temp) result = 1.0;
else result = 0.0;
break;
case '=':
if(l_temp == r_temp) result = 1.0;
else result = 0.0;
break;
case NE:
if(l_temp != r_temp) result = 1.0;
else result = 0.0;
break;
}
}
return result;
}
// Add or subtract two terms.
private double evalExp2() throws InterpreterException
{
char op;
double result;
double partialResult;
result = evalExp3();
while((op = token.charAt(0)) == '+' || op == '-') {
getToken();
partialResult = evalExp3();
switch(op) {
case '-':
result = result - partialResult;
break;
case '+':
result = result + partialResult;
break;
}
}
return result;
}
// Multiply or divide two factors.
private double evalExp3() throws InterpreterException
{
char op;
double result;
double partialResult;
result = evalExp4();
while((op = token.charAt(0)) == '*' ||
op == '/' || op == '%') {
getToken();
partialResult = evalExp4();
switch(op) {
case '*':
result = result * partialResult;
break;
case '/':
if(partialResult == 0.0)
handleErr(DIVBYZERO);
result = result / partialResult;
break;
case '%':
if(partialResult == 0.0)
handleErr(DIVBYZERO);
result = result % partialResult;
break;
}
}
return result;
}
// Process an exponent.
private double evalExp4() throws InterpreterException
{
double result;
double partialResult;
double ex;
int t;
result = evalExp5();
if(token.equals("^")) {
getToken();
partialResult = evalExp4();
ex = result;
if(partialResult == 0.0) {
result = 1.0;
} else
for(t=(int)partialResult-1; t > 0; t--)
result = result * ex;
}
return result;
}
// Evaluate a unary + or -.
private double evalExp5() throws InterpreterException
{
double result;
String op;
op = "";
if((tokType == DELIMITER) &&
token.equals("+") || token.equals("-")) {
op = token;
getToken();
}
result = evalExp6();
if(op.equals("-")) result = -result;
return result;
}
// Process a parenthesized expression.
private double evalExp6() throws InterpreterException
{
double result;
if(token.equals("(")) {
getToken();
result = evalExp2();
if(!token.equals(")"))
handleErr(UNBALPARENS);
getToken();
}
else result = atom();
return result;
}
// Get the value of a number or variable.
private double atom() throws InterpreterException
{
double result = 0.0;
switch(tokType) {
case NUMBER:
try {
result = Double.parseDouble(token);
} catch (NumberFormatException exc) {
handleErr(SYNTAX);
}
getToken();
break;
case VARIABLE:
result = findVar(token);
getToken();
break;
default:
handleErr(SYNTAX);
break;
}
return result;
}
// Return the value of a variable.
private double findVar(String vname)
throws InterpreterException
{
if(!Character.isLetter(vname.charAt(0))){
handleErr(SYNTAX);
return 0.0;
}
return vars[Character.toUpperCase(vname.charAt(0))-'A'];
}
// Return a token to the input stream.
private void putBack()
{
if(token == EOP) return;
for(int i=0; i < token.length(); i++) progIdx--;
}
// Handle an error.
private void handleErr(int error)
throws InterpreterException
{
String[] err = {
"Syntax Error",
"Unbalanced Parentheses",
"No Expression Present",
"Division by Zero",
"Equal sign expected",
"Not a variable",
"Label table full",
"Duplicate label",
"Undefined label",
"THEN expected",
"TO expected",
"NEXT without FOR",
"RETURN without GOSUB",
"Closing quotes needed",
"File not found",
"I/O error while loading file",
"I/O error on INPUT statement"
};
throw new InterpreterException(err[error]);
}
// Obtain the next token.
private void getToken() throws InterpreterException
{
char ch;
tokType = NONE;
token = "";
kwToken = UNKNCOM;
// Check for end of program.
if(progIdx == prog.length) {
token = EOP;
return;
}
// Skip over white space.
while(progIdx < prog.length &&
isSpaceOrTab(prog[progIdx])) progIdx++;
// Trailing whitespace ends program.
if(progIdx == prog.length) {
token = EOP;
tokType = DELIMITER;
return;
}
if(prog[progIdx] == '\r') { // handle crlf
progIdx += 2;
kwToken = EOL;
token = "\r\n";
return;
}
// Check for relational operator.
ch = prog[progIdx];
if(ch == '<' || ch == '>') {
if(progIdx+1 == prog.length) handleErr(SYNTAX);
switch(ch) {
case '<':
if(prog[progIdx+1] == '>') {
progIdx += 2;;
token = String.valueOf(NE);
}
else if(prog[progIdx+1] == '=') {
progIdx += 2;
token = String.valueOf(LE);
}
else {
progIdx++;
token = "<";
}
break;
case '>':
if(prog[progIdx+1] == '=') {
progIdx += 2;;
token = String.valueOf(GE);
}
else {
progIdx++;
token = ">";
}
break;
}
tokType = DELIMITER;
return;
}
if(isDelim(prog[progIdx])) {
// Is an operator.
token += prog[progIdx];
progIdx++;
tokType = DELIMITER;
}
else if(Character.isLetter(prog[progIdx])) {
// Is a variable or keyword.
while(!isDelim(prog[progIdx])) {
token += prog[progIdx];
progIdx++;
if(progIdx >= prog.length) break;
}
kwToken = lookUp(token);
if(kwToken==UNKNCOM) tokType = VARIABLE;
else tokType = COMMAND;
}
else if(Character.isDigit(prog[progIdx])) {
// Is a number.
while(!isDelim(prog[progIdx])) {
token += prog[progIdx];
progIdx++;
if(progIdx >= prog.length) break;
}
tokType = NUMBER;
}
else if(prog[progIdx] == '"') {
// Is a quoted string.
progIdx++;
ch = prog[progIdx];
while(ch !='"' && ch != '\r') {
token += ch;
progIdx++;
ch = prog[progIdx];
}
if(ch == '\r') handleErr(MISSINGQUOTE);
progIdx++;
tokType = QUOTEDSTR;
}
else { // unknown character terminates program
token = EOP;
return;
}
}
// Return true if c is a delimiter.
private boolean isDelim(char c)
{
if((" \r,;<>+-/*%^=()".indexOf(c) != -1))
return true;
return false;
}
// Return true if c is a space or a tab.
boolean isSpaceOrTab(char c)
{
if(c == ' ' || c =='\t') return true;
return false;
}
// Return true if c is a relational operator.
boolean isRelop(char c) {
if(relops.indexOf(c) != -1) return true;
return false;
}
/* Look up a token's internal representation in the
token table. */
private int lookUp(String s)
{
int i;
// Convert to lowercase.
s = s.toLowerCase();
// See if token is in table.
for(i=0; i < kwTable.length; i++)
if(kwTable[i].keyword.equals(s))
return kwTable[i].keywordTok;
return UNKNCOM; // unknown keyword
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -