混合两种语言

时间:2019-02-07 19:17:47

标签: antlr4

我正在为一种小型元语言编写语法。该语言应包括另一种语言的代码块(例如,JavaScrip,C或类似语言)。我想将这些代码块仅视为未打印输出的纯字符串。我的语言是基于c / Java语法的,将{}用于代码块。但是我也想对嵌入式语言的代码块使用'{''}'。下面是一些示例代码:

// my language
modul Abc {
   input x: string;
   otherLang {
      // this is now a code block from the second
      // language, which I do not want to analyze
      // It might itself contain { } like
      if (something) {
          abc = "string";
      }
   }
}

如何将{}用于那些不同的用途,而又不将它们与嵌入式语言的用途混为一谈?

1 个答案:

答案 0 :(得分:1)

一个有趣的方法是使用模式递归。 ANTLR在内部维护模式堆栈。

虽然有点冗长,但是递归模式提供了处理诸如注释和转义字符之类的东西的可能性,否则它们可能会抛出嵌套。

要知道的一件事是,具有more属性的规则将它们匹配的内容连接到随后的第一个未受more规则生成的令牌中。以下示例使用虚拟令牌OTHER_END来提供语义清晰性,并避免与否则为RPAREN令牌的混淆。

tokens {
    OTHER_END
}

otherLang : OTHER_BEG OTHER_END+ ; // multiple 'end's dependent on nesting

OTHER_BEG : 'otherLang' LPAREN -> pushMode(Other) ;
LPAREN    : LParen ;
RPAREN    : RParen ;
WS        : [ \t\r\n] -> skip;

mode Other ;
    // handle special cases here 
    O_RPAREN : RParen -> type(OTHER_END), popMode() ;
    O_LPAREN : LParen -> more, pushMode(Other) ;
    O_STUFF  : .      -> more ;

fragment LParen : '{' ;
fragment RParen : '}' ;