将解析器用于OData v4语法 [英] Using parser for OData v4 grammar

查看:87
本文介绍了将解析器用于OData v4语法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用OASIS组提供的Antlr4的OData v4语法.请参阅以下链接: https ://tools.oasis-open.org/version-control/browse/wsvn/odata/trunk/spec/grammar/ANTLR/#_trunk_spec_grammar_ANTLR_

I try to use the OData v4 grammar for Antlr4 provided by the OASIS group. See the following link: https://tools.oasis-open.org/version-control/browse/wsvn/odata/trunk/spec/grammar/ANTLR/#_trunk_spec_grammar_ANTLR_

基于这些文件和Antlr v4 Maven插件,我成功生成了用于解析OData URL的类.

Based on these files and Antlr v4 Maven plugin, I successfully generated classes to parse OData URLs.

我尝试如下所述使用解析器:

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

调用方法odataUri时,我在错误侦听器中报告了以下错误:

When calling the method odataUri, I have the following error reported in the error listener:

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"

也许odataUri方法不是解析器上要调用的方法.但是,在阅读解析器语法文件之后,情况似乎确实如此.

Perhaps the method odataUri isn't the one to call on the parser. But after having read the parser grammar file, it seems to be the case.

-于12/01修改

我检测到规则名称有问题:

I detected a problem with a rule name:

odataUri : Protocol ColSlaSla host ( COLON port )?
       serviceRoot
       ( ODataSignal_METADATA | ODataSignal_BATCH | odataRelativeUri )? EOF;

Protocol :  

找不到规则Protocol.如果我将其名称更新为protocol,那就更好了...

The rule Protocol can't be found. If I updated its name to protocol, it's much better...

按照Bart的建议,我打印了与令牌关联的规则的名称.使用Antlr4 maven插件生成的插件,我无法获得正确的插件.在经典一代中,我有这个:

Following Bart's advice, I printed the names of rules associated with tokens. With a generated with Antlr4 maven plugin, I can't get the correct ones. 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.

我还启用了解析器(parser.setTrace(true))上的跟踪,然后再次执行我的代码.我仍然有错误

I also enabled trace on the parser (parser.setTrace(true)) and execute again my code. 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):

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];

这篇关于将解析器用于OData v4语法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆