This repository has been archived on 2024-11-28. You can view files and clone it, but cannot push or open issues or pull requests.
Incam_SGD/search2/search/SearchCommandParser.y

212 lines
3.0 KiB
Plaintext

%name SearchCommandParser
%declare_class {class SearchCommandParser}
%include_class {
private $expr_result;
private $parse_result;
public function __construct()
{
$this->parse_result = 'ok';
}
public function getExprResult()
{
return $this->expr_result;
}
public function isExprOk()
{
return $this->parse_result == 'ok';
}
}
%type expr {Expr}
%left OPOR.
%left OPAND.
%right NOT.
%left IS CONTAIN LIKE BETWEEN START END.
%left GT LE LT GE.
%syntax_error
{
$this->parse_result = 'syntax';
$this->parse_message = "";
}
%parse_accept
{
$this->parse_result = 'ok';
}
%parse_failure
{
$this->parse_result = 'syntax';
}
%start_symbol cmdline
cmdline ::= expr(A).
{
$this->expr_result = A;
}
expr(A) ::= expr(B) OPAND expr(C).
{
A = new OpExpr(B, ExprOp::OP_AND, C);
}
expr(A) ::= expr(B) OPOR expr(C).
{
A = new OpExpr(B, ExprOp::OP_OR, C);
}
expr(A) ::= NOT expr(B).
{
$expr = B;
$expr->not(!$expr->not());
A = $expr;
}
expr(A) ::= PAR_OPEN expr(B) PAR_CLOSE.
{
A = B;
}
expr(A) ::= terminal(B) operator(C) value(D).
{
$op = C;
$not = false;
if ($op == ExprOp::IS_NOT)
{
$op = ExprOp::IS;
$not = true;
}
$fld = new OpExpr(B, $op, D);
$fld->not($not);
A = $fld;
}
expr(A) ::= terminal(B) notop(C) BETWEEN value(D) OPAND value(E). [BETWEEN]
{
$expr = new OpExpr(B, ExprOp::BETWEEN, new BetweenValueExpr(D, E));
$expr->not(C);
A=$expr;
}
expr(A) ::= terminal(B) notop(C) LIKE value(D).
{
$expr = new OpExpr(B, ExprOp::LIKE, D);
$expr->not(C);
A=$expr;
}
expr(A) ::= terminal(B) IS notop(C) value(D).
{
$expr = new OpExpr(B, ExprOp::IS, D);
$expr->not(C);
A=$expr;
}
expr(A) ::= terminal(B) DOES notop(C) CONTAINS value(D).
{
$expr = new OpExpr(B, ExprOp::CONTAINS, D);
$expr->not(C);
A=$expr;
}
expr(A) ::= terminal(B) COLON value(C).
{
A = new OpExpr(B, ExprOp::CONTAINS, C);
}
notop(A) ::= .
{
A = false;
}
notop(A) ::= NOT.
{
A = true;
}
terminal(A) ::= SQUARE_OPEN value(B) SQUARE_CLOSE SQUARE_OPEN value(C) SQUARE_CLOSE.
{
$registry = ExprFieldRegistry::getRegistry();
$field = $registry->resolveMetadataField(B, C);
A = $field;
}
terminal(A) ::= TERMINAL(B).
{
$registry = ExprFieldRegistry::getRegistry();
$field=$registry->resolveAlias(B);
A = $field;
}
value(A) ::= VALUE(B).
{
A = B;
}
value(A) ::= PAR_OPEN valuelist(B) PAR_CLOSE.
{
A = B;
}
valuelist(A) ::= VALUE(B) COMMA valuelist(C).
{
C->addValue(B);
A = C;
}
valuelist(A) ::= VALUE(B).
{
A = new ValueListExpr(B);
}
operator(A) ::= CONTAINS.
{
A = ExprOp::CONTAINS;
}
operator(A) ::= LT.
{
A = ExprOp::LESS_THAN;
}
operator(A) ::= GT.
{
A = ExprOp::GREATER_THAN;
}
operator(A) ::= LE.
{
A = ExprOp::LESS_THAN_EQUAL;
}
operator(A) ::= GE.
{
A = ExprOp::GREATER_THAN_EQUAL;
}
operator(A) ::= START WITH.
{
A = ExprOp::STARTS_WITH;
}
operator(A) ::= END WITH.
{
A = ExprOp::ENDS_WITH;
}
operator(A) ::= IS_NOT.
{
A = ExprOp::IS_NOT;
}