git ANTLR4中的词汇标记歧义

piv4azn7  于 2023-02-07  发布在  Git
关注(0)|答案(1)|浏览(128)

我有一个非常有趣的问题,解析下面的语法(Convnetional Commits)-这是一个约定git提交消息应该如何格式化。

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]
  • 正文是简单的多行文本,其中包含任何内容
  • 页脚是具有fobar: this is value的键值对,并以换行符分隔它们。

关于我的困境区分body部分和footer部分的最好方法是什么?根据规范,它们应该用两个换行符分隔,所以一开始我认为这很适合ANTLR 4岛语法。我想出了类似于我发布的here的东西,但是经过一些测试,我发现它不灵活--如果没有主体(主体部分是可选的),但页脚,它就不起作用。
我可以想到几种方法来限制语法到特定的语言,并通过语义 predicate 实现这种区分,但理想情况下,我希望避免这种情况。
现在,我认为问题归结为如何正确区分冲突的KEYSINGLE_LINE标记(在我的实现的下一次迭代中)

mode Text;
KEY: [a-z][a-z_-]+;
SINGLE_LINE: ~[\n]+;

MULTI_LINE: SINGLE_LINE (NEWLINE SINGLE_LINE)*;

NEXT: NEWLINE NEWLINE;

区分KEYSINGLE_LINE的最佳方法是什么?

enxuqcxy

enxuqcxy1#

我会这样做:

会议委员会文件. g4

lexer grammar ConventionalCommitsLexer;

options {
  caseInsensitive=true;
}

TYPE : [a-z]+;
LPAR : '(' -> pushMode(Scope);
COL  : ':' -> pushMode(Text);

fragment SPACE : [ \t];

mode Scope;

 SCOPE : ~[)]+;
 RPAR  : ')' SPACE* -> popMode;

mode Text;

 COL2    : ':' -> type(COL);
 SPACES : SPACE+ -> skip;
 WORD   : ~[: \t\r\n]+;
 NL     : SPACE* '\r'? '\n' SPACE*;

常规提交解析器.g4

parser grammar ConventionalCommitsParser;

options {
  tokenVocab=ConventionalCommitsLexer;
}

commit
 : TYPE scope? COL description ( NL NL body )? ( NL NL footer )? EOF
 ;

scope
 : LPAR SCOPE RPAR
 ;

description
 : word+
 ;

// A 'body' cannot start with `WORD COL`, hence: `WORD WORD`
body
 : WORD WORD word* ( NL word+ )*
 ;

footer
 : key_value ( NL key_value )* NL?
 ;

key_value
 : WORD COL word+
 ;

word
 : WORD
 | COL
 ;

解析输入(正文+页脚):

fix(some_module): this is a commit description
    
Some more in-depth description of what was fixed: this
can be a multi-line text, not only a one-liner.

Signed-off: john.doe@some.domain.com
Another-Key: another value with : (colon)
Some-Other-Key: some other value

结果:

解析输入(仅正文):

fix(some_module): this is a commit description
    
Some more in-depth description of what was fixed: this
can be a multi-line text, not only a one-liner.

结果:

解析输入(仅页脚):

fix(some_module): this is a commit description

Signed-off: john.doe@some.domain.com
Another-Key: another value with : (colon)
Some-Other-Key: some other value

结果:

相关问题