[英]Using parser for OData v4 grammar
I try to use the OData v4 grammar for Antlr4 provided by the OASIS group. 我尝试对OASIS组提供的Antlr4使用OData v4语法。 See the following link: https://tools.oasis-open.org/version-control/browse/wsvn/odata/trunk/spec/grammar/ANTLR/#_trunk_spec_grammar_ANTLR_
请参阅以下链接: https : //tools.oasis-open.org/version-control/browse/wsvn/odata/trunk/spec/grammar/ANTLR/#_trunk_spec_grammar_ANTLR_
Based on these files and Antlr v4 Maven plugin, I successfully generated classes to parse OData URLs. 基于这些文件和Antlr v4 Maven插件,我成功生成了用于解析OData URL的类。
I try to use the parser as described below: 我尝试如下所述使用解析器:
String expression = "http://192.168.1.1/odata/Category(1)/Products?$top=2&$orderby=name";
ANTLRInputStream in = new ANTLRInputStream(expression);
ODataParserLexer lexer = new ODataParserLexer(in);
ODataParserParser parser = new ODataParserParser(
new CommonTokenStream(lexer));
ODataErrorListener errorListener = new ODataErrorListener();
parser.addErrorListener(errorListener);
ODataParseListener listener = new ODataParseListener();
parser.addParseListener(listener);
OdataUriContext ctx = parser.odataUri();
When calling the method odataUri, I have the following error reported in the error listener: 调用方法odataUri时,我在错误侦听器中报告了以下错误:
line 1:66 mismatched input '<EOF>' expecting Protocol
This is strange since the lexer is able to get tokens for the string to parse: 这很奇怪,因为词法分析器能够获取要解析的字符串的令牌:
"http"
"://"
"192.168.1.1"
"/"
"odata"
"/"
"Category"
"("
"1"
")"
"/"
"Products"
"?"
"$top"
"="
"2"
"&"
"$orderby"
"="
"name"
Perhaps the method odataUri isn't the one to call on the parser. 也许odataUri方法不是解析器上要调用的方法。 But after having read the parser grammar file, it seems to be the case.
但是在阅读解析器语法文件后,情况似乎确实如此。
-- Edited on 12/01 -编辑于12/01
I detected a problem with a rule name: 我检测到规则名称有问题:
odataUri : Protocol ColSlaSla host ( COLON port )?
serviceRoot
( ODataSignal_METADATA | ODataSignal_BATCH | odataRelativeUri )? EOF;
Protocol :
The rule Protocol
can't be found. 找不到规则
Protocol
。 If I updated its name to protocol
, it's much better... 如果我将其名称更新为
protocol
,那就更好了...
Following Bart's advice, I printed the names of rules associated with tokens. 按照Bart的建议,我打印了与令牌关联的规则的名称。 With a generated with Antlr4 maven plugin, I can't get the correct ones.
使用Antlr4 maven插件生成的插件,我无法获得正确的插件。 With the classic generation, I have this:
在经典一代中,我有以下几点:
"http"
index = 93, ODataParserLexer.tokenNames[index] = HTTPORHTTPS
"://"
index = 92, ODataParserLexer.tokenNames[index] = ColSlaSla
"192.168.1.1"
index = 23, ODataParserLexer.tokenNames[index] = Ls32
"/"
index = 60, ODataParserLexer.tokenNames[index] = '/'
"odata"
index = 4, ODataParserLexer.tokenNames[index] = 'odata'
"/"
index = 60, ODataParserLexer.tokenNames[index] = '/'
"Category"
index = 251, ODataParserLexer.tokenNames[index] = ODATA_ID_CHAR8
"("
index = 28, ODataParserLexer.tokenNames[index] = SubDelims
"1"
index = 25, ODataParserLexer.tokenNames[index] = DecOctet
")"
index = 28, ODataParserLexer.tokenNames[index] = SubDelims
"/"
index = 60, ODataParserLexer.tokenNames[index] = '/'
"Products"
index = 251, ODataParserLexer.tokenNames[index] = ODATA_ID_CHAR8
"?"
index = 66, ODataParserLexer.tokenNames[index] = '?'
"$top"
index = 128, ODataParserLexer.tokenNames[index] = ODataSignal_TOP
"="
index = 28, ODataParserLexer.tokenNames[index] = SubDelims
"2"
index = 25, ODataParserLexer.tokenNames[index] = DecOctet
"&"
index = 28, ODataParserLexer.tokenNames[index] = SubDelims
"$orderby"
index = 126, ODataParserLexer.tokenNames[index] = ODataSignal_ORDERBY
"="
index = 28, ODataParserLexer.tokenNames[index] = SubDelims
"name"
index = 250, ODataParserLexer.tokenNames[index] = ODATA_ID_CHAR4
The tokens and associated rules seems correct. 令牌和相关规则似乎正确。
I also enabled trace on the parser ( parser.setTrace(true)
) and execute again my code. 我还启用了对解析器(
parser.setTrace(true)
)的跟踪,然后再次执行我的代码。 I still have an error 我仍然有一个错误
enter odataUri, LT(1)=<EOF>
enter protocol, LT(1)=<EOF>
line 1:66 mismatched input '<EOF>' expecting HTTPORHTTPS
------------
Error on query :
null
=> line 1 : mismatched input '<EOF>' expecting HTTPORHTTPS
Context : [590]
exit protocol, LT(1)=<EOF>
exit odataUri, LT(1)=<EOF>
Thanks very much for your help. 非常感谢您的帮助。 Thierry
蒂埃里
The grammar specified has a lot of ambiguous matches and needed to be rewritten to eliminate ambiguous matches possibly using semantic predicates or lexer modes. 指定的语法有很多歧义匹配,可能需要使用语义谓词或词法分析器模式进行重写以消除歧义匹配。 For expamle (i rewrote grammar start rules):
对于expamle(我重写了语法开始规则):
odataUri : serviceRoot? EOF ;
serviceRoot : Protocol host segments relative? # OnSerivceRoot ;
segments : Segments ;
host : (addr | regName) port?;
addr : ColSlaSla IPv4address ;
regName : HOST ;
port : PortDef ;
relative : (ODataSignal_METADATA | ODataSignal_BATCH) | odataRelativeUri;
odataRelativeUri : resourcePath ( question queryOptions )?;
question : QUESTION ;
PortDef : COLON Digits ;
Segments : SLASH ((Unreserved | PctEncoded | SubDelims | COLON | AT_SIGN)+ SLASH)* ;
HOST : ColSlaSla HOST_DEF ;
HOST_DEF : (Unreserved | PctEncoded | SubDelims)+ ;
QUESTION : '?';
Protocol : HttpOrHttpsAnyCase;
Digits : Digit+ ;
Digit : [0-9] ;
Alpha : [a-zA-Z];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.