Summary description for PrologOperator.
        public bool ExclusivelyPrefix(string name)
        {
            if (IsOperator(name))
            {
                return(true);
            }
            PrologOperator op = GetOperator(name);

            if (op != null)
            {
                return(op.PostfixPrecedence == -1);
            }
            return(false);
        }
        public void AddPostfixOperator(string name, bool right, int precedence)
        {
            PrologOperator op = null;

            if (IsOperator(name))
            {
                op = GetOperator(name);
                op.PostfixPrecedence    = precedence;
                op.IsPostfixAssociative = right;
            }
            else
            {
                op = new PrologOperator(name, 0, precedence, 0);
                op.IsPrefixAssociative = right;
                _operatorTable.Add(name, op);
            }
        }
Пример #3
0
        public void AddPostfixOperator(string name, bool right, int precedence)
        {
            PrologOperator op = null;

            if (IsOperator(name))
            {
                op = GetOperator(name);
                op.PostfixPrecedence = precedence;
                op.IsPostfixAssociative = right;
            }
            else
            {
                op = new PrologOperator(name, 0, precedence, 0);
                op.IsPrefixAssociative = right;
                _operatorTable.Add(name, op);
            }
        }
Пример #4
0
 public void AddInfixOperator(string name, bool left, bool right, int precedence)
 {
     PrologOperator op = null;
     if (IsOperator(name))
     {
         op = GetOperator(name);
         op.InfixPrecedence = precedence;
         op.IsInfixLeftAssociative = left;
         op.IsInfixRightAssociative = right;
     }
     else
     {
         op = new PrologOperator(name, 0, 0, precedence);
         op.IsInfixLeftAssociative = left;
         op.IsInfixRightAssociative = right;
         _operatorTable.Add(name, op);
     }
 }
        public void AddInfixOperator(string name, bool left, bool right, int precedence)
        {
            PrologOperator op = null;

            if (IsOperator(name))
            {
                op = GetOperator(name);
                op.InfixPrecedence         = precedence;
                op.IsInfixLeftAssociative  = left;
                op.IsInfixRightAssociative = right;
            }
            else
            {
                op = new PrologOperator(name, 0, 0, precedence);
                op.IsInfixLeftAssociative  = left;
                op.IsInfixRightAssociative = right;
                _operatorTable.Add(name, op);
            }
        }
        private BinaryTree Right(int n, int m, ref BinaryTree result)
        {
            switch (_scanner.Lookahead.Kind)
            {
            case PrologToken.DOT:
            case PrologToken.RPAREN:
            case PrologToken.RBRACKET:
                return(result);

            case PrologToken.LPAREN:
            case PrologToken.LBRACKET:
                _errors.Add(new PrologCompilerError("P0007", "Unexpected open brackets or parenthsis", "", false, _scanner.Current.Line, _scanner.Current.Column));
                return(result);

            case PrologToken.COMMA:
                if (n >= 1000 && m <= 1000)
                {
                    m = 1000;
                    _scanner.Next();
                    result = new BinaryTree(",", result, Term(m));
                    if (n > m)
                    {
                        Right(n, m, ref result);
                    }
                }
                return(result);

            case PrologToken.ATOM:
                PrologOperator laOp = _operators.GetOperator(_scanner.Lookahead.StringValue);
                if (laOp != null)
                {
                    if (laOp.IsPostfix &&
                        n >= laOp.PostfixPrecedence &&
                        m <= laOp.PostfixLeftPrecedence)
                    {
                        _scanner.Next();
                        if (_operators.IsOperator(_scanner.Current.StringValue))
                        {
                            PrologOperator o = _operators.GetOperator(_scanner.Current.StringValue);
                            if (o.IsInfix &&
                                n >= o.InfixPrecedence &&
                                m <= o.InfixLeftPrecedence)
                            {
                                switch (_scanner.Lookahead.Kind)
                                {
                                case PrologToken.LPAREN:
                                case PrologToken.LBRACKET:
                                    result = new BinaryTree(o.Name, result, Term(o.InfixRightPrecedence));
                                    m      = o.InfixPrecedence;
                                    Right(n, m, ref result);
                                    break;

                                case PrologToken.COMMA:
                                case PrologToken.RPAREN:
                                case PrologToken.RBRACKET:
                                    result = new BinaryTree(_scanner.Current.StringValue, result);
                                    m      = o.InfixPrecedence;
                                    Right(n, m, ref result);
                                    break;

                                case PrologToken.ATOM:
                                    if (_operators.IsOperator(_scanner.Lookahead.StringValue))
                                    {
                                        if (_operators.ExclusivelyPrefix(_scanner.Lookahead.StringValue))
                                        {
                                            result = new BinaryTree(_scanner.Lookahead.StringValue, result, Term(_operators.GetOperator(_scanner.Lookahead.StringValue).PrefixRightPrecedence));
                                            m      = o.InfixPrecedence;
                                            Right(n, m, ref result);
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        result = new BinaryTree(_scanner.Lookahead.StringValue, result, null);
                                        m      = _operators.GetOperator(_scanner.Lookahead.StringValue).InfixPrecedence;
                                        Right(n, m, ref result);
                                        break;
                                    }
                                    break;
                                }
                            }
                            else
                            {
                                result = new BinaryTree(_scanner.Current.StringValue, result);
                                m      = _operators.GetOperator(_scanner.Current.StringValue).InfixPrecedence;
                                Right(n, m, ref result);
                            }
                        }
                        break;
                    }
                    else if (laOp.IsInfix && n >= laOp.InfixPrecedence && m <= laOp.InfixLeftPrecedence)
                    {
                        _scanner.Next();
                        int p = _operators.GetOperator(_scanner.Current.StringValue).InfixPrecedence;
                        int t = _operators.GetOperator(_scanner.Current.StringValue).InfixRightPrecedence;
                        result = new BinaryTree(_scanner.Current.StringValue, result, Term(t));
                        m      = p;
                        Right(n, m, ref result);
                        break;
                    }
                }
                else
                {
                    return(result);
                }
                break;
            }
            return(result);
        }
        public BinaryTree Term(int n)
        {
            int        m   = 0;
            BinaryTree ast = null;

            _scanner.Next();
            switch (_scanner.Current.Kind)
            {
            case PrologToken.LPAREN:
                ast = Term(1200);
                _scanner.Next();
                if (_scanner.Current.Kind != PrologToken.RPAREN)
                {
                    _errors.Add(new PrologCompilerError("P0003", "Expected ) after term", "", false, _scanner.Current.Line, _scanner.Current.Column));
                }
                break;

            // Handle list terms here...
            case PrologToken.LBRACKET:
                ArrayList listArguments = new ArrayList();
                // Peek after [ token
                if (_scanner.Lookahead.Kind == PrologToken.RBRACKET)
                {
                    _scanner.Next();
                    // return a nil atom: []
                    ast = new BinaryList();     // empty list
                    break;
                }
                listArguments.Add(Term(999));
                _scanner.Next();

                // if , is encountered
                while (_scanner.Current.Kind == PrologToken.COMMA)
                {
                    listArguments.Add(Term(999));
                    _scanner.Next();
                }
                if (_scanner.Current.Kind == PrologToken.LIST_SEP)
                {
                    listArguments.Add(Term(999));
                    _scanner.Next();
                }
                else
                {
                    listArguments.Add(new BinaryList());
                }
                if (_scanner.Current.Kind != PrologToken.RBRACKET)
                {
                    _errors.Add(new PrologCompilerError("P0004", "Unterminated list, expected ]", "", false, _scanner.Current.Line, _scanner.Current.Column));
                }

                int        i    = listArguments.Count - 1;
                BinaryList list = new BinaryList((BinaryTree)listArguments[i - 1], (BinaryTree)listArguments[i]);
                i -= 2;
                while (i > -1)
                {
                    list = new BinaryList((BinaryTree)listArguments[i--], list);
                }
                ast = list;
                break;

            case PrologToken.RPAREN:
            case PrologToken.RBRACKET:
            case PrologToken.COMMA:
            case PrologToken.DOT:
                _errors.Add(new PrologCompilerError("P0005", "Unexpected closure of term", "", false, _scanner.Current.Line, _scanner.Current.Column));
                return(null);

            case PrologToken.ATOM:
            case PrologToken.VARIABLE:
                string atomName = _scanner.Current.StringValue;
                if (_scanner.Lookahead.Kind == PrologToken.LPAREN)
                {
                    ArrayList arguments = new ArrayList();
                    _scanner.Next();
                    arguments.Add(Term(1200));

                    _scanner.Next();
                    while (_scanner.Current.Kind == PrologToken.COMMA)
                    {
                        arguments.Add(Term(1200));
                        _scanner.Next();
                    }
                    if (_scanner.Current.Kind != PrologToken.RPAREN)
                    {
                        _errors.Add(new PrologCompilerError("P0005", "Unexpected closure of term", "", false, _scanner.Current.Line, _scanner.Current.Column));
                        return(null);
                    }
                    ast = new BinaryTree(atomName, arguments);
                    break;
                }
                if (_operators.IsOperator(_scanner.Current.StringValue))
                {
                    PrologOperator op = _operators.GetOperator(_scanner.Current.StringValue);
                    if (op.IsPrefix)
                    {
                        // prefix operator
                        if (n < op.PrefixPrecedence)
                        {
                            ParserError("prefix precedence error", _scanner.Current.Line, _scanner.Current.Column);
                            return(null);
                        }
                        switch (_scanner.Lookahead.Kind)
                        {
                        case PrologToken.LPAREN:
                        case PrologToken.LBRACKET:
                            ast = new BinaryTree(op.Name, Term(op.PrefixRightPrecedence));
                            m   = op.PrefixPrecedence;
                            Right(n, m, ref ast);
                            break;

                        case PrologToken.RPAREN:
                        case PrologToken.RBRACKET:
                        case PrologToken.DOT:
                        case PrologToken.LIST_SEP:
                            if (n < m)
                            {
                                _errors.Add(new PrologCompilerError("P0006", "Unexpected atom '" + _scanner.Lookahead.StringValue + "'", "", false, _scanner.Current.Line, _scanner.Current.Column));
                                return(null);
                            }
                            ast = new BinaryTree(_scanner.Current.StringValue);
                            Right(n, m, ref ast);
                            break;

                        case PrologToken.ATOM:
                            if (_operators.IsOperator(_scanner.Lookahead.StringValue))
                            {
                                PrologOperator atomOp = _operators.GetOperator(_scanner.Lookahead.StringValue);
                                if (atomOp.IsInfix && m <= atomOp.InfixLeftPrecedence)
                                {
                                    if (n < m)
                                    {
                                        ParserError("n < m", _scanner.Lookahead.Line, _scanner.Current.Column);
                                        return(null);
                                    }
                                    ast = new BinaryTree(_scanner.Lookahead.StringValue);
                                    Right(n, m, ref ast);
                                    break;
                                }
                                else if (atomOp.IsPostfix && m <= atomOp.PostfixLeftPrecedence)
                                {
                                    if (n < m)
                                    {
                                        ParserError("n < m", _scanner.Current.Line, _scanner.Current.Column);
                                        return(null);
                                    }
                                    ast = new BinaryTree(_scanner.Current.StringValue);
                                    Right(n, m, ref ast);
                                    break;
                                }
                                // Just added on 6/23/2006. Might not fix anything.
                                else
                                {
                                    ast = new BinaryTree(_scanner.Current.StringValue, null, Term(op.InfixRightPrecedence));
                                    m   = op.PrefixPrecedence;
                                    Right(n, m, ref ast);
                                    break;
                                }
                            }
                            else
                            {
                                ast = new BinaryTree(_scanner.Current.StringValue, null, Term(op.InfixRightPrecedence));
                                m   = op.PrefixPrecedence;
                                Right(n, m, ref ast);
                            }
                            break;

                        default:
                            ParserError("Unknown internal error", _scanner.Current.Line, _scanner.Current.Column);
                            return(null);
                        }
                    }
                }
                else
                {
                    ast = new BinaryTree(_scanner.Current.StringValue);
                }
                break;

            default:
                ParserError("Unknown internal error", _scanner.Current.Line, _scanner.Current.Column);
                return(null);
            }
            Right(n, m, ref ast);
            return(ast);
        }