无法在 Antlr4 中实现带有自定义分隔符的 q 引用字符串

Posted

技术标签:

【中文标题】无法在 Antlr4 中实现带有自定义分隔符的 q 引用字符串【英文标题】:No way to implement a q quoted string with custom delimiters in Antlr4 【发布时间】:2018-09-21 10:01:08 【问题描述】:

我正在尝试为 oracle Q 引用字符串机制实现词法分析器规则,其中我们有类似 q'$some string$' 的东西

在这里,您可以使用任何字符代替 $,而不是空格、(、、[、

这是我尝试实施规则的方式:

Q_QUOTED_LITERAL: Q_QUOTED_LITERAL_NON_TERMINATED . QUOTE-> type(QUOTED_LITERAL); 

Q_QUOTED_LITERAL_NON_TERMINATED:
    Q QUOTE ~[ ([<'"\t\n\r]  setDelimChar( (char)_input.LA(-1) );  
    ( .  !isValidEndDelimChar() ? )* 
;

我已经检查了从 !isValidEndDelimChar() 获得的值,并且我在正确的地方得到了一个错误的谓词,所以一切都应该正常工作,但 antlr 只是忽略了这个谓词。我也尝试过移动谓词,将该部分放在单独的规则中,以及一堆其他东西,经过一天半的研究,我终于提出了这个问题。

我也尝试以其他方式实现它,但似乎没有办法在 antlr4 中实现自定义字符分隔字符串(antlr3 版本曾经工作)。

【问题讨论】:

【参考方案1】:

不确定为什么不调用 ... 操作,但它不是必需的。以下语法对我有用(将谓词放在.!之前):

grammar Test;

@lexer::members 
  boolean isValidEndDelimChar() 
    return (_input.LA(1) == getText().charAt(2)) && (_input.LA(2) == '\'');
  


parse
 : .*? EOF
 ;

Q_QUOTED_LITERAL
 : 'q\'' ~[ ([<'"\t\n\r] ( !isValidEndDelimChar()? . )* . '\''
 ;

SPACE
 : [ \t\f\r\n] -> skip
 ;

如果你运行课程:

import org.antlr.v4.runtime.*;

public class Main 

  public static void main(String[] args) 

    Lexer lexer = new TestLexer(CharStreams.fromString("q'ssome strings' q'!foo!'"));
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    tokens.fill();

    for (Token t : tokens.getTokens()) 
      System.out.printf("%-20s %s\n", TestLexer.VOCABULARY.getSymbolicName(t.getType()), t.getText());
    
  

将打印以下输出:

Q_QUOTED_LITERAL     q'ssome strings'
Q_QUOTED_LITERAL     q'!foo!'
EOF                  <EOF>

【讨论】:

你是一个救生员。原来在 isValidEndDelimChar() 中用 (_input.LA(1) == getText().charAt(2)) 替换 (_input.LA(1) == delimChar) 是我所需要的。奇怪的是,即使我从函数的两个实现中得到了相同的响应,但我的旧版本却无法结束闭包。再次感谢! 很高兴听到@user3770822!

以上是关于无法在 Antlr4 中实现带有自定义分隔符的 q 引用字符串的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 中实现 - 带有自定义标记器的 Android MultiAutoCompleteTextView,如 Whatsapp [附加图片]

如何在iOS swift中实现带有月份、日期和时间的自定义选择器?

如何在 QT 中实现自定义模型的 removeRow() 函数?

如何在自定义相机中实现“捏放大”

在spring boot中实现自定义错误

在自定义指令 angular 4 中实现 onclick()