2
我想创建一个词法规则,可以读取一个字符串文字,它定义了自己的分隔符(具体而言,甲骨文的报价分隔字符串):如何编写引用字符的词法分析器规则?
q'!My string which can contain 'single quotes'!'
其中!
作为分隔符,但在理论上成为任何角色。
是否有可能通过词法分析规则做到这一点,而不会引入对给定语言目标的依赖关系?
我想创建一个词法规则,可以读取一个字符串文字,它定义了自己的分隔符(具体而言,甲骨文的报价分隔字符串):如何编写引用字符的词法分析器规则?
q'!My string which can contain 'single quotes'!'
其中!
作为分隔符,但在理论上成为任何角色。
是否有可能通过词法分析规则做到这一点,而不会引入对给定语言目标的依赖关系?
是否可以通过词法分析规则做到这一点,而不会引入对给定语言目标的依赖关系?
不,目标相关的代码是需要这样的事情。
万一你或其他人读这个问答&一个想知道这是如何使用的目标代码来完成,这里有一个快速演示:
lexer grammar TLexer;
@members {
boolean ahead(String text) {
for (int i = 0; i < text.length(); i++) {
if (_input.LA(i + 1) != text.charAt(i)) {
return false;
}
}
return true;
}
}
TEXT
: [nN]? (['] ([']['] | ~['])* [']
| [qQ] ['] QUOTED_TEXT [']
)
;
// Skip everything other than TEXT tokens
OTHER
: . -> skip
;
fragment QUOTED_TEXT
: '[' ({!ahead("]'")}? .)* ']'
| '{' ({!ahead("}'")}? .)* '}'
| '<' ({!ahead(">'")}? .)* '>'
| '(' ({!ahead(")'")}? .)* ')'
| . ({!ahead(getText().charAt(0) + "'")}? .)* .
;
可与类测试:
public class Main {
static void test(String input) {
TLexer lexer = new TLexer(new ANTLRInputStream(input));
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
tokenStream.fill();
System.out.printf("input: `%s`\n", input);
for (Token token : tokenStream.getTokens()) {
if (token.getType() != TLexer.EOF) {
System.out.printf(" token: -> %s\n", token.getText());
}
}
System.out.println();
}
public static void main(String[] args) throws Exception {
test("foo q'!My string which can contain 'single quotes'!' bar");
test("foo q'(My string which can contain 'single quotes')' bar");
test("foo 'My string which can contain ''single quotes' bar");
}
}
,它将打印:
input: `foo q'!My string which can contain 'single quotes'!' bar`
token: -> q'!My string which can contain 'single quotes'!'
input: `foo q'(My string which can contain 'single quotes')' bar`
token: -> q'(My string which can contain 'single quotes')'
input: `foo 'My string which can contain ''single quotes' bar`
token: -> 'My string which can contain ''single quotes'
的.
在替代
| . ({!ahead(getText().charAt(0) + "'")}? .)* .
可能有点太宽容,但可以通过将其替换为否定或常规字符集来调整。