如何在ANTLR中编写Tcl嵌套字符串规则?

时间:2012-03-26 22:00:11

标签: escaping nested antlr bnf

Tcl嵌套字符串可以是这样的:

{abc {xyz foo {hello world}}}

上面的大括号用于包含字符串的内容,它们不是字符串的一部分(类似于双引号)。并且可以使用"\{""\}"转义它们以将字符串"foo"更改为"foo{}"

{abc {xyz foo\{\} {hello world}}}

对于没有括号转义的那个,我有一个有效的词法规则:

NestedBraces
  :  '{' ( ~('{'|'}') | NestedBraces)* '}'
  ;

我正在尝试找到一种方法来添加转义部分,同时保持嵌套语法,并且到目前为止还没有成功。

2 个答案:

答案 0 :(得分:0)

试试这个:

NestedBraces
 : '{' (~('{' | '}' | '\\') | '\\' ('{' | '}') | NestedBraces)* '}'
 ;

在内部循环中,您匹配:

~('{' | '}' | '\\')   // anything other than a '{', '}' and '\'
|                     // OR
'\\' ('{' | '}')      // an escaped '{' or '}' 
|                     // OR
NestedBraces          // recursive call: '{' ... '}'

如果你想一次性从令牌中剥离未转义的大括号,请执行以下操作:

NestedBraces
 : Helper {setText($text.replaceAll("\\\\(.)|[{}]", "$1"));}
 ;

fragment Helper
 : '{' (~('{' | '}' | '\\') | '\\' ('{' | '}') | Helper)* '}'
 ;

将为输入"abc xyz foo{ hello world"创建内部文字为"{abc {xyz foo\{ {hello world}}}"的令牌。请注意,您需要一个帮助程序规则:您不能在一个规则中执行替换的递归调用。

答案 1 :(得分:0)

谢谢,巴特。

无法在评论部分正确输入代码,因此我在此处粘贴代码:

NestedBraces
:   '{'(EscapeBraces | ~('{'|'}') | NestedBraces)* '}';
fragment
EscapeBraces
:   '\\' 
    (
    '{' 
    | '}' 
    )
;