如何弹出模式两次/弹出而不消耗

时间:2014-12-12 18:50:10

标签: antlr antlr4

这是输入的一个例子:

<span class="hello">cont@(Property)ent</span>

这是我当前语法的一个例子(简化;如果有语法错误,那是因为我的书面简化):

TAG_OPEN
  : '<' -> pushMode(TAG_MODE)
  ;

mode TAG_MODE;

TAG_CLOSE
  : '>' -> popMode
  ;

TAG_EQUALS
  : '=' -> pushMode(ATTRIBUTE_MODE)
  ;

mode ATTRIBUTE_MODE;

ATTRIBUTE_OPEN
  : '"' -> pushMode(ATTRIBUTE_CONTENT_MODE)
  ;

mode ATTRIBUTE_CONTENT_MODE;

// Code removed that deals with the matching of the @(Property)

ATTRIBUTE_CLOSE
  : '"' -> popMode
  ;

ATTRIBUTE_CONTENT
  : ~["]* // Simplified
  ;

以完美的方式匹配标记及其属性,以及引用字符串的open + content + close。 但是它不能再匹配了,因为(或者我认为是这样的)我们已经陷入了 ATTRIBUTE_MODE 并且无法回到 TAG_MODE 因为&#34; 字符已消耗, ATTRIBUTE_MODE &gt; 无法匹配

所以我收到错误消息:&#34;令牌识别错误:&#39;&gt;&#39;&#34;&#34;

不,我不能简单地将整个字符串作为一个符号匹配,例如:

DOUBLE_QUOTE_STRING
  : '"' ~[<"]* '"'
  ;

因为我必须单独匹配输入的 @(Property)。它必须是引用字符串中属性内容的单独标记。

所以我的问题是: 有没有办法弹出几种模式?我正在寻找的是:

ATTRIBUTE_CLOSE
  : '"' -> popMode(2)
  ;

ATTRIBUTE_CLOSE
  : '"' -> popMode, skipButDoNotConsumeCurrentCharacter
  ;

&#34;跳过&#34;在这里不起作用,因为它消耗并持续到下一场比赛。然后我会尝试以某种方式从 ATTRIBUTE_MODE 弹出到 TAG_MODE

或者我从一开始就设计了这个完全错误的东西?

感谢您提供任何帮助/建议!

1 个答案:

答案 0 :(得分:1)

如果你想进行双重弹出,你可以这样做:

ATTRIBUTE_CLOSE 
 : '"' -> popMode, popMode 
 ;