匹配任何字符直到遇到 XYZ 的 ANTLR 4 令牌规则
ANTLR 4 token rule that matches any characters until it encounters XYZ
我想要一个令牌规则吞噬所有字符,直到到达字符 XYZ
。
因此,如果输入是这样的:
helloXYZ
那么令牌规则应该return这个令牌:
hello
如果输入是这样的:
Blah Blah XYZ
那么令牌规则应该return这个令牌:
Blah Blah
如何定义令牌规则来执行此操作?
这个怎么样?
HELLO : 'hello' {_input.LA(1)!=' '}? ;
根据 Terrance 在他的回答中给出的提示,我认为这就是 Roger 正在寻找的内容:
grammar UseLookahead;
parserRule : LexerRule;
LexerRule : .+? { (_input.LA(1) == 'X') &&
(_input.LA(2) == 'Y') &&
(_input.LA(3) == 'Z')
}?
;
这给出了所需的答案,分别为 hello
和 Blah Blah
。我承认我不明白最后的 ?
.
的意义
如果你想要好的性能,你需要使用不使用谓词的形式。如果令牌以 XYZ
.
结尾,我将使用仿照 PositionAdjustingLexer.g4 的代码重置位置
编辑: 不要低估使用语义谓词的答案对性能的影响。谓词将至少对整个输入流的每个字符进行一次评估,并且会阻止对谓词进行评估的任何字符使用 DFA。上次我看到这样的东西在使用中,它负责整个解析过程 95% 以上的执行时间,删除它可以将性能从 20 秒以上提高到不到 1 秒。
tokens {
SpecialToken
}
mode SpecialTokenMode;
// In your position adjusting lexer, if you see a token with the type
// SpecialTokenWithXYZ, reset the position to remove the last 3 characters and set
// the type to SpecialToken
SpecialTokenWithXYZ
: 'XYZ'
-> popMode
;
SpecialTokenCharacterAtEOF
: . EOF
-> type(SpecialToken), popMode
;
SpecialTokenCharacter
: .
-> more
;
如果您想要甚至更好 性能,您可以添加一些规则来优化不包含任何 X
个字符的序列的处理:
tokens {
SpecialToken
}
mode SpecialTokenMode;
// In your position adjusting lexer, if you see a token with the type
// SpecialTokenWithXYZ, reset the position to remove the last 3 characters and set
// the type to SpecialToken
SpecialTokenWithXYZ
: 'XYZ'
-> popMode
;
SpecialTokenCharacterSpanAtEOF
: ~'X'+ EOF
-> type(SpecialToken), popMode
;
SpecialTokenCharacterSpan
: ~'X'+
-> more
;
SpecialTokenXAtEOF
: 'X' EOF
-> type(SpecialToken), popMode
;
SpecialTokenX
: 'X'
-> more
;
我想要一个令牌规则吞噬所有字符,直到到达字符 XYZ
。
因此,如果输入是这样的:
helloXYZ
那么令牌规则应该return这个令牌:
hello
如果输入是这样的:
Blah Blah XYZ
那么令牌规则应该return这个令牌:
Blah Blah
如何定义令牌规则来执行此操作?
这个怎么样?
HELLO : 'hello' {_input.LA(1)!=' '}? ;
根据 Terrance 在他的回答中给出的提示,我认为这就是 Roger 正在寻找的内容:
grammar UseLookahead;
parserRule : LexerRule;
LexerRule : .+? { (_input.LA(1) == 'X') &&
(_input.LA(2) == 'Y') &&
(_input.LA(3) == 'Z')
}?
;
这给出了所需的答案,分别为 hello
和 Blah Blah
。我承认我不明白最后的 ?
.
如果你想要好的性能,你需要使用不使用谓词的形式。如果令牌以 XYZ
.
编辑: 不要低估使用语义谓词的答案对性能的影响。谓词将至少对整个输入流的每个字符进行一次评估,并且会阻止对谓词进行评估的任何字符使用 DFA。上次我看到这样的东西在使用中,它负责整个解析过程 95% 以上的执行时间,删除它可以将性能从 20 秒以上提高到不到 1 秒。
tokens {
SpecialToken
}
mode SpecialTokenMode;
// In your position adjusting lexer, if you see a token with the type
// SpecialTokenWithXYZ, reset the position to remove the last 3 characters and set
// the type to SpecialToken
SpecialTokenWithXYZ
: 'XYZ'
-> popMode
;
SpecialTokenCharacterAtEOF
: . EOF
-> type(SpecialToken), popMode
;
SpecialTokenCharacter
: .
-> more
;
如果您想要甚至更好 性能,您可以添加一些规则来优化不包含任何 X
个字符的序列的处理:
tokens {
SpecialToken
}
mode SpecialTokenMode;
// In your position adjusting lexer, if you see a token with the type
// SpecialTokenWithXYZ, reset the position to remove the last 3 characters and set
// the type to SpecialToken
SpecialTokenWithXYZ
: 'XYZ'
-> popMode
;
SpecialTokenCharacterSpanAtEOF
: ~'X'+ EOF
-> type(SpecialToken), popMode
;
SpecialTokenCharacterSpan
: ~'X'+
-> more
;
SpecialTokenXAtEOF
: 'X' EOF
-> type(SpecialToken), popMode
;
SpecialTokenX
: 'X'
-> more
;