Parsing JavaCC:像对待<;或>;
我正在尝试为搜索引擎查询构建一个简单的语法。 到目前为止我已经知道了-Parsing JavaCC:像对待<;或>;,parsing,grammar,javacc,Parsing,Grammar,Javacc,我正在尝试为搜索引擎查询构建一个简单的语法。 到目前为止我已经知道了- options { STATIC=false; MULTI=true; VISITOR=true; } PARSER_BEGIN(SearchParser) package com.syncplicity.searchservice.infrastructure.parser; public class SearchParser {} PARSER_END(SearchParser) SKIP : { "
options {
STATIC=false;
MULTI=true;
VISITOR=true;
}
PARSER_BEGIN(SearchParser)
package com.syncplicity.searchservice.infrastructure.parser;
public class SearchParser {}
PARSER_END(SearchParser)
SKIP :
{
" "
| "\t"
| "\n"
| "\r"
}
<*> TOKEN : {
<#_TERM_CHAR: ~[ " ", "\t", "\n", "\r", "!", "(", ")", "\"", "\\", "/" ] >
| <#_QUOTED_CHAR: ~["\""] >
| <#_WHITESPACE: ( " " | "\t" | "\n" | "\r" | "\u3000") >
}
TOKEN :
{
<AND: "AND">
| <OR: "OR">
| <NOT: ("NOT" | "!")>
| <LBRACKET: "(">
| <RBRACKET: ")">
| <TERM: (<_TERM_CHAR>)+ >
| <QUOTED: "\"" (<_QUOTED_CHAR>)+ "\"">
}
/** Main production. */
ASTQuery query() #Query: {}
{
subQuery()
( <AND> subQuery() #LogicalAnd
| <OR> subQuery() #LogicalOr
| <NOT> subQuery() #LogicalNot
)*
{
return jjtThis;
}
}
void subQuery() #void: {}
{
<LBRACKET> query() <RBRACKET> | term() | quoted()
}
void term() #Term:
{
Token t;
}
{
(
t=<TERM>
)
{
jjtThis.value = t.image;
}
}
void quoted() #Quoted:
{
Token t;
}
{
(
t=<QUOTED>
)
{
jjtThis.value = t.image;
}
}
选项{
静态=假;
多=真;
访客=真实;
}
解析器_BEGIN(SearchParser)
包com.syncplicity.searchservice.infrastructure.parser;
公共类SearchParser{}
解析器_END(SearchParser)
跳过:
{
" "
|“\t”
|“\n”
|“\r”
}
代币:{
|
}
代币:
{
|
|
|
|
|
|
}
/**主要生产*/
ASTQuery查询()#查询:{}
{
子查询()
(子查询()#LogicalAnd
|子查询()#逻辑逻辑
|子查询()#逻辑不
)*
{
将此返回jjt;
}
}
void子查询()#void:{}
{
查询()|术语()|引号()
}
无效术语()#术语:
{
令牌t;
}
{
(
t=
)
{
jjthis.value=t.image;
}
}
无效报价()#报价:
{
令牌t;
}
{
(
t=
)
{
jjthis.value=t.image;
}
}
看起来它像我想要的那样工作,例如它可以处理和,或者,不是/代码>,单个术语和引用文本
但是,我不能强制它将术语之间的空格处理为或运算符。例如,hello world
应被视为hello或world
我已经尝试了所有明显的解决方案,例如
,从跳过中删除”
,等等。但它仍然不起作用。也许您不希望空白被视为OR,也许您希望OR关键字是可选的。在这种情况下,你可以使用这样的语法
query --> subquery (<AND> subquery | (<OR>)? subquery | <NOT> subquery)*
query() --> query0() ows() <EOF>
query0() --> query1()
( LOOKAHEAD( ows() <OR> | ws() (<NOT> | <LBRACKET> | <TERM> | <QUOTED>) )
( ows() (<OR>)?
query1()
)*
query1() --> query2() (LOOKAHEAD(ows() <AND>) ows() <AND> query2())*
query2() --> ows() (<NOT> query2() | subquery())
subquery() --> <LBRACKET> query0() ows() <RBRACKET> | <TERM> | <QUOTED>
ows() --> (<WS>)*
ws() --> (<WS>)+
query-->子查询(子查询|()?子查询|子查询)*
但是,该语法不将其视为中缀运算符。而且它也不反映优先级。通常不优先于或。此外,您的主要产品应寻找EOF。你可以试试看
query --> query0 <EOF>
query0 --> query1 ((<OR>)? query1)*
query1 --> query2 (<AND> query2)*
query2 --> <NOT> query2 | subquery
subquery --> <LBRACKET> query0 <RBRACKET> | <TERM> | <QUOTED>
query-->查询0
查询0-->查询1(()?查询1)*
查询1-->查询2(查询2)*
query2-->query2 |子查询
子查询-->查询0 | |
也许您不希望将空格视为OR,也许您希望OR关键字是可选的。在这种情况下,你可以使用这样的语法
query --> subquery (<AND> subquery | (<OR>)? subquery | <NOT> subquery)*
query() --> query0() ows() <EOF>
query0() --> query1()
( LOOKAHEAD( ows() <OR> | ws() (<NOT> | <LBRACKET> | <TERM> | <QUOTED>) )
( ows() (<OR>)?
query1()
)*
query1() --> query2() (LOOKAHEAD(ows() <AND>) ows() <AND> query2())*
query2() --> ows() (<NOT> query2() | subquery())
subquery() --> <LBRACKET> query0() ows() <RBRACKET> | <TERM> | <QUOTED>
ows() --> (<WS>)*
ws() --> (<WS>)+
query-->子查询(子查询|()?子查询|子查询)*
但是,该语法不将其视为中缀运算符。而且它也不反映优先级。通常不优先于或。此外,您的主要产品应寻找EOF。你可以试试看
query --> query0 <EOF>
query0 --> query1 ((<OR>)? query1)*
query1 --> query2 (<AND> query2)*
query2 --> <NOT> query2 | subquery
subquery --> <LBRACKET> query0 <RBRACKET> | <TERM> | <QUOTED>
query-->查询0
查询0-->查询1(()?查询1)*
查询1-->查询2(查询2)*
query2-->query2 |子查询
子查询-->查询0 | |
好的。假设您确实希望至少用一个空格替换任何缺少的OR。或者换句话说,如果有一个或多个空格允许使用Or,则该空格被视为Or
在我的另一个解决方案中,我将不作为一元运算符处理,并且不优先于和优先于或
改变
SKIP : { " " | "\t" | "\n" | "\r" }
到
TOKEN:{}
现在用这样的语法
query --> subquery (<AND> subquery | (<OR>)? subquery | <NOT> subquery)*
query() --> query0() ows() <EOF>
query0() --> query1()
( LOOKAHEAD( ows() <OR> | ws() (<NOT> | <LBRACKET> | <TERM> | <QUOTED>) )
( ows() (<OR>)?
query1()
)*
query1() --> query2() (LOOKAHEAD(ows() <AND>) ows() <AND> query2())*
query2() --> ows() (<NOT> query2() | subquery())
subquery() --> <LBRACKET> query0() ows() <RBRACKET> | <TERM> | <QUOTED>
ows() --> (<WS>)*
ws() --> (<WS>)+
query()-->query0()ows()
query0()-->query1()
(向前看(ows()| ws()(| | |)
(ows()()?
问题1()
)*
query1()-->query2()(先行(ows())ows()query2())*
query2()-->ows()(query2()|子查询())
子查询()-->query0()ows()||
ows()-->()*
ws()-->()+
好的。假设您确实希望用至少一个空格替换任何缺失的Or。或者换句话说,如果允许使用Or的地方有一个或多个空格,则该空格被视为Or
在我的另一个解决方案中,我将不作为一元运算符处理,并且不优先于和优先于或
改变
SKIP : { " " | "\t" | "\n" | "\r" }
到
TOKEN:{}
现在用这样的语法
query --> subquery (<AND> subquery | (<OR>)? subquery | <NOT> subquery)*
query() --> query0() ows() <EOF>
query0() --> query1()
( LOOKAHEAD( ows() <OR> | ws() (<NOT> | <LBRACKET> | <TERM> | <QUOTED>) )
( ows() (<OR>)?
query1()
)*
query1() --> query2() (LOOKAHEAD(ows() <AND>) ows() <AND> query2())*
query2() --> ows() (<NOT> query2() | subquery())
subquery() --> <LBRACKET> query0() ows() <RBRACKET> | <TERM> | <QUOTED>
ows() --> (<WS>)*
ws() --> (<WS>)+
query()-->query0()ows()
query0()-->query1()
(向前看(ows()| ws()(| | |)
(ows()()?
问题1()
)*
query1()-->query2()(先行(ows())ows()query2())*
query2()-->ows()(query2()|子查询())
子查询()-->query0()ows()||
ows()-->()*
ws()-->()+
事实上,我真的希望空白被视为。这是搜索引擎的常见行为。当您键入hello world
-它将同时搜索hello
和world
(除非搜索短语被引用:“hello world”
-但这种情况在我的语法中已经很好用了)如果您有一个如何实现的想法,我会非常感激。
就像或一样,所以您希望“hello”“world”
不被视为“hello”或“world”
。而且(hello)(world)
不应该被视为(hello)或(world)
。那么(“hello”)(world)呢
:那应该被视为(“hello”或)(world)
?可能不是。确切地说,哪些空格应该被视为OR,哪些空格不应该被视为?编辑为需要EOF。@沉默框Theodore是对的:hello world
有两个标记,hello world
,而helloword
和“hello world”
有一个。是可选的。实际上我真的希望空白被视为。这是搜索引擎的常见行为。当你键入hello world
时,它将同时搜索hello
和world
(除非搜索短语被引用:“hello world”)“
-但这种情况在我的语法中已经很好了)如果你能想到如何实现”
比如或者,我会非常感激,所以你希望“hello”“world”
不被视为“hello”或者“world”
。而(hello)(world)
不应该被视为(hello)或者(world)。(“hello”)(世界)
:应该被视为(“hello”或(世界)
?可能不是。确切地说,什么空白应该被视为OR,什么空白应该被视为OR