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); } }
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); }