我有这个语法:
grammar ProcedureHeaderLanguage ;
@header
{
package com.company.generated.antlr.atr;
}
fragment DIGIT
: '0'..'9'
;
fragment A
: [aA]
;
fragment B
: [bB]
;
fragment C
: [cC]
;
fragment D
: [dD]
;
fragment E
: [eE]
;
fragment F
: [fF]
;
fragment G
: [gG]
;
fragment H
: [hH]
;
fragment I
: [iI]
;
fragment J
: [jJ]
;
fragment K
: [kK]
;
fragment L
: [lL]
;
fragment M
: [mM]
;
fragment N
: [nN]
;
fragment O
: [oO]
;
fragment P
: [pP]
;
fragment Q
: [qQ]
;
fragment R
: [rR]
;
fragment S
: [sS]
;
fragment T
: [tT]
;
fragment U
: [uU]
;
fragment V
: [vV]
;
fragment W
: [wW]
;
fragment X
: [xX]
;
fragment Y
: [yY]
;
fragment Z
: [zZ]
;
fragment DIGIT_PAIR
: DIGIT DIGIT
;
fragment ALPHA
: 'a'..'z'
| 'A'..'Z'
;
SEMICOLON
: ';'
;
HYPHEN
: '-'
;
PROCEDURE_IDENTIFIER
: P R O C E D U R E
;
COMMA
: ','
;
LEFT_PARENTHESIS
: '('
;
RIGHT_PARENTHESIS
: ')'
;
dataField
: IDENTIFIER
;
nameField
: dataField
;
parameterNameField
: dataField
;
dataTypeField
: dataField
;
IN
: I N
;
WS
: (' ' | '\t' | '\r' | '\n')+ -> skip
;
IDENTIFIER
: (ALPHA | '_') (ALPHA | DIGIT | '_')*
;
COMMENT
: HYPHEN HYPHEN
;
parameterPair
: parameterNameField IN dataTypeField
;
procedureName
: PROCEDURE_IDENTIFIER nameField
;
procedureParameter
: LEFT_PARENTHESIS parameterPair (COMMA parameterPair)* RIGHT_PARENTHESIS
;
procedure
: procedureName procedureParameter SEMICOLON
;
procedures
: procedure (procedure)*
;
能够解析以下示例:
sorten_COBB_SEK in number,
sorten_COBB_VORG in number,
然而,解析文件不仅包含此类数据。
它还将存储一些可选的而非强制性的信息。
我知道我可以简单地告诉他们?
是可选的,但事情并非那么简单。
我还有这个例子:
sorten_FEUCHTE_MIN in number,
sorten_FEUCHTE_MAX in number,
sorten_FEUCHTE_SPERR in number,
sorten_LEIMUNG in varchar2, -- J or N
sorten_BEMERKUNG in varchar2
其中-- J or N
与sorten_LEIMUNG条目相关联,我想获取该条目的信息。问题是分隔符COMMA在我要解析的注释之前。
所以这样的语法不起作用:
parameterPair
: parameterNameField IN dataTypeField COMMA? COMMENT? dataField?
;
procedureParameter
: LEFT_PARENTHESIS parameterPair (parameterPair)* RIGHT_PARENTHESIS
;
如何实现为同一条目(同一行)注册评论的目标?
编辑:如上所述,上述语法将正确解析第一个例子。然而,第二个将被打破。它会将or
检测为新parameterName
。
通过第二次语法更改,我能够解析-- J
,而其余的将被检测为新的parameterName。
我如何告诉antlr解析我的意愿,或者这是一个限制,我最好告诉用户不要在他的评论中使用空格?
答案 0 :(得分:0)
没有你的整个语法,我无法进行真正的测试,但我会尝试为你提出建议。由于您的评论标识符--
必须是连续的,因此我将该规则编码为:
TEXT: ALPHA | DIGIT;
TEXTS : TEXT*;
COMMENT
: '--' TEXTS
;
这样可以确保您的--
评论+混合文字作为评论获得作为。
答案 1 :(得分:0)
您的COMMENT
规则不完整。它只包含评论介绍人,但没有任何内容应与该行的其余部分相匹配。一种典型的方法是:
SINGLE_LINE_COMMENT: '--' ~([\r\n] | EOF)*;
答案 2 :(得分:0)
由于我刚刚开始使用ANTLR,我不知道这是否是最佳解决方案,但是使用语法规则:
SINGLE_LINE_COMMENT
: '--' (.)*? '\r'? '\n'
;
parameterPair
: parameterNameField IN dataTypeField COMMA? SINGLE_LINE_COMMENT?
;
然后我可以在自定义访问者中执行此操作:
/**
* Filters out the needed informations of the antlr parser context and
* creates the POJO {@link SqlParameter} with it.
*
* @param parameterPair the parameter pair
* @return the sql parameter
*/
private SqlParameter createParameter( ParameterPairContext parameterPair )
{
final String parameterName = parameterPair.parameterNameField().getText();
final String dataType = parameterPair.dataTypeField().getText();
Optional<String> comment = Optional.empty();
if ( parameterPair.SINGLE_LINE_COMMENT() != null )
{
comment = Optional.ofNullable( parameterPair.SINGLE_LINE_COMMENT().getText().trim() );
}
return new SqlParameter( parameterName, dataType, comment );
}
在所有情况下哪个都不实用,但现在应该做到这一点。将其记录下来将导致我需要的东西:
StringBuilder log = new StringBuilder();
log.append( "Parameter: " );
log.append( parameter.getParameterName() );
log.append( " with type: " );
log.append( parameter.getParameterType() );
parameter.getComment().ifPresent( comment -> log.append( " with comment: " ).append( comment ) );
>>>>>>>>>>>>>>>>>>>>>>>>>>>
Parameter: sorten_FEUCHTE_SPERR with type: number
Parameter: sorten_LEIMUNG with type: varchar2 with comment: -- J or N
Parameter: sorten_BEMERKUNG with type: varchar2