Search in sources :

Example 1 with OperatorType

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;
}
Also used : ExpValue(priv.bajdcc.LALR1.grammar.tree.ExpValue) Token(priv.bajdcc.util.lexer.token.Token) OperatorType(priv.bajdcc.util.lexer.token.OperatorType)

Example 2 with OperatorType

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;
}
Also used : IExpCollction(priv.bajdcc.LL1.syntax.exp.IExpCollction) BranchExp(priv.bajdcc.LL1.syntax.exp.BranchExp) SequenceExp(priv.bajdcc.LL1.syntax.exp.SequenceExp) OperatorType(priv.bajdcc.LL1.syntax.token.OperatorType)

Example 3 with OperatorType

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;
}
Also used : ExpValue(priv.bajdcc.LALR1.grammar.tree.ExpValue) Token(priv.bajdcc.util.lexer.token.Token) OperatorType(priv.bajdcc.util.lexer.token.OperatorType)

Example 4 with OperatorType

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();
    }
}
Also used : RuntimeInstUnary(priv.bajdcc.LALR1.grammar.runtime.RuntimeInstUnary) RuntimeInst(priv.bajdcc.LALR1.grammar.runtime.RuntimeInst) OperatorType(priv.bajdcc.util.lexer.token.OperatorType)

Example 5 with OperatorType

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";
}
Also used : Token(priv.bajdcc.util.lexer.token.Token) Grammar(priv.bajdcc.LALR1.grammar.Grammar) OperatorType(priv.bajdcc.util.lexer.token.OperatorType) SyntaxException(priv.bajdcc.OP.syntax.handler.SyntaxException) GrammarException(priv.bajdcc.OP.grammar.error.GrammarException) RegexException(priv.bajdcc.util.lexer.error.RegexException) IPatternHandler(priv.bajdcc.OP.grammar.handler.IPatternHandler)

Aggregations

OperatorType (priv.bajdcc.util.lexer.token.OperatorType)5 Token (priv.bajdcc.util.lexer.token.Token)4 ExpValue (priv.bajdcc.LALR1.grammar.tree.ExpValue)2 RegexException (priv.bajdcc.util.lexer.error.RegexException)2 Grammar (priv.bajdcc.LALR1.grammar.Grammar)1 RuntimeInst (priv.bajdcc.LALR1.grammar.runtime.RuntimeInst)1 RuntimeInstUnary (priv.bajdcc.LALR1.grammar.runtime.RuntimeInstUnary)1 Semantic (priv.bajdcc.LALR1.semantic.Semantic)1 ISemanticAnalyzer (priv.bajdcc.LALR1.semantic.token.ISemanticAnalyzer)1 BranchExp (priv.bajdcc.LALR1.syntax.exp.BranchExp)1 IExpCollction (priv.bajdcc.LALR1.syntax.exp.IExpCollction)1 OptionExp (priv.bajdcc.LALR1.syntax.exp.OptionExp)1 PropertyExp (priv.bajdcc.LALR1.syntax.exp.PropertyExp)1 SequenceExp (priv.bajdcc.LALR1.syntax.exp.SequenceExp)1 SyntaxException (priv.bajdcc.LALR1.syntax.handler.SyntaxException)1 OperatorType (priv.bajdcc.LALR1.syntax.token.OperatorType)1 BranchExp (priv.bajdcc.LL1.syntax.exp.BranchExp)1 IExpCollction (priv.bajdcc.LL1.syntax.exp.IExpCollction)1 SequenceExp (priv.bajdcc.LL1.syntax.exp.SequenceExp)1 OperatorType (priv.bajdcc.LL1.syntax.token.OperatorType)1