2016-04-27 48 views
2

我想创建一个词法规则,可以读取一个字符串文字,它定义了自己的分隔符(具体而言,甲骨文的报价分隔字符串):如何编写引用字符的词法分析器规则?

q'!My string which can contain 'single quotes'!' 

其中!作为分隔符,但在理论上成为任何角色。

是否有可能通过词法分析规则做到这一点,而不会引入对给定语言目标的依赖关系?

回答

3

是否可以通过词法分析规则做到这一点,而不会引入对给定语言目标的依赖关系?

不,目标相关的代码是需要这样的事情。

万一你或其他人读这个问答&一个想知道这是如何使用的目标代码来完成,这里有一个快速演示:

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) + "'")}? .)* . 

可能有点太宽容,但可以通过将其替换为否定或常规字符集来调整。

相关问题