use of priv.bajdcc.LALR1.syntax.token.OperatorType in project jMiniLang by bajdcc.
the class TokenTools method sinop.
/**
* 单目运算
*
* @param recorder 错误记录
* @param exp 表达式
* @return 运算是否合法
*/
public static boolean sinop(ISemanticRecorder recorder, ExpSinop exp) {
ExpValue value = (ExpValue) exp.getOperand();
Token token = value.getToken();
OperatorType type = (OperatorType) exp.getToken().object;
if (sin(type, token)) {
return true;
}
recorder.add(SemanticError.INVALID_OPERATOR, token);
return false;
}
use of priv.bajdcc.LALR1.syntax.token.OperatorType in project jMiniLang by bajdcc.
the class Syntax method doAnalysis.
/**
* 分析表达式
*
* @param type
* 结束类型
* @param obj
* 结束数据
* @return 表达式树根结点
* @throws SyntaxException 词法错误
*/
private ISyntaxComponent doAnalysis(TokenType type, Object obj) throws SyntaxException {
/* 新建序列用于存放结果 */
SequenceExp sequence = new SequenceExp();
/* 可能会使用的分支 */
BranchExp branch = null;
/* 添加子结点接口 */
IExpCollction collection = sequence;
/* 表达式通用接口 */
ISyntaxComponent result = sequence;
for (; ; ) {
if ((token.kToken == type && (token.object == null || token.object.equals(obj)))) {
// 结束字符
if (syntaxLexer.index() == 0) {
// 表达式为空
err(SyntaxError.NULL);
} else if (collection.isEmpty()) {
// 部件为空
err(SyntaxError.INCOMPLETE);
} else {
next();
// 正常终止
break;
}
} else if (token.kToken == TokenType.EOF) {
err(SyntaxError.INCOMPLETE);
}
// 当前待赋值的表达式
ISyntaxComponent exp = null;
switch(token.kToken) {
case OPERATOR:
OperatorType op = (OperatorType) token.object;
next();
switch(op) {
case ALTERNATIVE:
if (// 在此之前没有存储表达式 (|...)
collection.isEmpty()) {
err(SyntaxError.INCOMPLETE);
} else {
if (branch == null) {
// 分支为空,则建立分支
branch = new BranchExp();
// 用新建的分支包含并替代当前序列
branch.add(sequence);
result = branch;
}
// 新建一个序列
sequence = new SequenceExp();
branch.add(sequence);
continue;
}
break;
default:
err(SyntaxError.SYNTAX);
break;
}
break;
case EOF:
return result;
case TERMINAL:
exp = matchTerminal();
next();
break;
case NONTERMINAL:
exp = matchNonTerminal();
next();
break;
default:
err(SyntaxError.SYNTAX);
break;
}
if (exp != null) {
sequence.add(exp);
}
}
return result;
}
use of priv.bajdcc.LALR1.syntax.token.OperatorType in project jMiniLang by bajdcc.
the class TokenTools method binop.
/**
* 双目运算
*
* @param recorder 错误记录
* @param exp 表达式
* @return 运算是否合法
*/
public static boolean binop(ISemanticRecorder recorder, ExpBinop exp) {
ExpValue leftValue = (ExpValue) exp.getLeftOperand();
ExpValue rightValue = (ExpValue) exp.getRightOperand();
Token token = exp.getToken();
Token leftToken = leftValue.getToken();
Token rightToken = rightValue.getToken();
OperatorType type = (OperatorType) token.object;
if (bin(type, leftToken, rightToken)) {
return true;
}
recorder.add(SemanticError.INVALID_OPERATOR, token);
return false;
}
use of priv.bajdcc.LALR1.syntax.token.OperatorType in project jMiniLang by bajdcc.
the class ExpBinop method genCode.
@Override
public void genCode(ICodegen codegen) {
if (token.kToken == TokenType.OPERATOR && token.object == OperatorType.DOT) {
codegen.genCode(RuntimeInst.iopena);
leftOperand.genCode(codegen);
codegen.genCode(RuntimeInst.ipusha);
rightOperand.genCode(codegen);
codegen.genCode(RuntimeInst.ipusha);
codegen.genCode(RuntimeInst.ipush, codegen.genDataRef("g_get_property"));
codegen.genCode(RuntimeInst.icallx);
return;
}
if (token.kToken == TokenType.OPERATOR) {
OperatorType op = (OperatorType) token.object;
if (TokenTools.isAssignment(op)) {
RuntimeInst ins = TokenTools.op2ins(token);
ExpValue left = (ExpValue) leftOperand;
if (ins == RuntimeInst.ice) {
rightOperand.genCode(codegen);
codegen.genCode(RuntimeInst.ipush, codegen.genDataRef(left.getToken().object));
codegen.genCode(RuntimeInst.istore);
return;
}
leftOperand.genCode(codegen);
rightOperand.genCode(codegen);
codegen.genCode(ins);
codegen.genCode(RuntimeInst.ipush, codegen.genDataRef(left.getToken().object));
codegen.genCode(RuntimeInst.istore);
return;
} else if (op == OperatorType.COLON) {
rightOperand.genCode(codegen);
leftOperand.genCode(codegen);
return;
}
}
RuntimeInst inst = TokenTools.op2ins(token);
leftOperand.genCode(codegen);
RuntimeInstUnary jmp = null;
switch(inst) {
case iandl:
jmp = codegen.genCode(RuntimeInst.ijfx, -1);
break;
case iorl:
jmp = codegen.genCode(RuntimeInst.ijtx, -1);
break;
default:
break;
}
rightOperand.genCode(codegen);
codegen.genCode(inst);
if (jmp != null) {
jmp.op1 = codegen.getCodeIndex();
}
}
use of priv.bajdcc.LALR1.syntax.token.OperatorType in project jMiniLang by bajdcc.
the class ModuleTask method util_calc.
private static String util_calc(String expr) {
try {
priv.bajdcc.OP.grammar.Grammar grammar = new priv.bajdcc.OP.grammar.Grammar(expr);
grammar.addTerminal("i", TokenType.INTEGER, null);
grammar.addTerminal("PLUS", TokenType.OPERATOR, OperatorType.PLUS);
grammar.addTerminal("MINUS", TokenType.OPERATOR, OperatorType.MINUS);
grammar.addTerminal("TIMES", TokenType.OPERATOR, OperatorType.TIMES);
grammar.addTerminal("DIVIDE", TokenType.OPERATOR, OperatorType.DIVIDE);
grammar.addTerminal("LPA", TokenType.OPERATOR, OperatorType.LPARAN);
grammar.addTerminal("RPA", TokenType.OPERATOR, OperatorType.RPARAN);
String[] nons = new String[] { "E", "T", "F" };
for (String non : nons) {
grammar.addNonTerminal(non);
}
grammar.addPatternHandler("1", new IPatternHandler() {
@Override
public Object handle(List<Token> tokens, List<Object> symbols) {
return Integer.parseInt(tokens.get(0).object.toString());
}
@Override
public String getPatternName() {
return "操作数转换";
}
});
grammar.addPatternHandler("010", new IPatternHandler() {
@Override
public Object handle(List<Token> tokens, List<Object> symbols) {
int lop = (int) symbols.get(0);
int rop = (int) symbols.get(1);
Token op = tokens.get(0);
if (op.kToken == TokenType.OPERATOR) {
OperatorType kop = (OperatorType) op.object;
switch(kop) {
case PLUS:
return lop + rop;
case MINUS:
return lop - rop;
case TIMES:
return lop * rop;
case DIVIDE:
if (rop == 0) {
return lop;
} else {
return lop / rop;
}
default:
return 0;
}
} else {
return 0;
}
}
@Override
public String getPatternName() {
return "二元运算";
}
});
grammar.addPatternHandler("101", new IPatternHandler() {
@Override
public Object handle(List<Token> tokens, List<Object> symbols) {
Token ltok = tokens.get(0);
Token rtok = tokens.get(1);
Object exp = symbols.get(0);
if (ltok.object == OperatorType.LPARAN && rtok.object == OperatorType.RPARAN) {
// 判断括号
return exp;
}
return null;
}
@Override
public String getPatternName() {
return "括号运算";
}
});
grammar.infer("E -> E @PLUS T | E @MINUS T | T");
grammar.infer("T -> T @TIMES F | T @DIVIDE F | F");
grammar.infer("F -> @LPA E @RPA | @i");
grammar.initialize("E");
return String.valueOf(grammar.run());
} catch (RegexException e) {
logger.error("#CALC# Error: " + e.getPosition() + "," + e.getMessage());
} catch (SyntaxException e) {
logger.error("#CALC#Error: " + e.getPosition() + "," + e.getMessage() + " " + e.getInfo());
} catch (GrammarException e) {
logger.error("#CALC#Error: " + e.getPosition() + "," + e.getMessage() + " " + e.getInfo());
}
return "#CALC#Error";
}
Aggregations