Antlr4解析规则匹配打开/关闭括号

  • 本文关键字:规则 Antlr4 antlr4
  • 更新时间 :
  • 英文 :


我正在解析一种具有语句'代码'的语言,其次是'{',然后是一堆我对解析的兴趣,然后是'}'。理想情况下,我想拥有一个规则:

skip_code: 'code' '{' ~['}']* '}'

..这只会跳到闭合的卷曲支架上。问题在于被跳过的代码本身可能具有成对的卷发括号。因此,我从本质上需要做的是运行计数器并在每个" {'"上递增每个"}",然后在计数器返回到0时结束解析规则。

在Antlr4中这样做的最好方法是什么?当检测到"代码"并吞下令牌并运行我的柜台时,我是否应该跳过自定义功能,还是在语法本身中表达这一点?

编辑:按要求的一些示例代码:

class foo;
  int m_bar;
  function foo_bar;
     print("hello world");
  endfunction
  code {
     // This is some C code
     void my_c_func() {
        printf("I have curly braces {} in a string!");
     }
  }
  function back_to_parsed_code;
  endfunction
endclass

我会使用以下内容:

skip_code: CODE_SYM block;
block: OPEN_CURLY (~CLOSE_CURLY | block)* CLOSE_CURLY;
CODE_SYM: 'code';
OPEN_CURLY: '{';
CLOSE_CURLY: '}';

我会在Lexer中处理这些代码块。快速演示:

import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.Token;
public class Main {
    public static void main(String[] args) {
        String source = "class foo;n" +
                "  int m_bar;n" +
                "  function foo_bar;n" +
                "     print("hello world");n" +
                "  endfunctionn" +
                "  code {n" +
                "     // This is some C code }}} n" +
                "     void my_c_func() {n" +
                "        printf("I have curly braces {} in a string!");n" +
                "     }n" +
                "  }n" +
                "  function back_to_parsed_code;n" +
                "  endfunctionn" +
                "endclass";
        System.out.printf("Tokenizing:nn%snn", source);
        DemoLexer lexer = new DemoLexer(new ANTLRInputStream(source));
        for (Token t : lexer.getAllTokens()){
            System.out.printf("%-20s '%s'n",
                    DemoLexer.VOCABULARY.getSymbolicName(t.getType()),
                    t.getText().replaceAll("[rn]", "\\n")
            );
        }
    }
}

如果您在上面运行类,则将打印以下内容:

Tokenizing:
class foo;
  int m_bar;
  function foo_bar;
     print("hello world");
  endfunction
  code {
     // This is some C code }}} 
     void my_c_func() {
        printf("I have curly braces {} in a string!");
     }
  }
  function back_to_parsed_code;
  endfunction
endclass
ID                   'class'
ID                   'foo'
ANY                  ';'
ID                   'int'
ID                   'm_bar'
ANY                  ';'
ID                   'function'
ID                   'foo_bar'
ANY                  ';'
ID                   'print'
ANY                  '('
STRING               '"hello world"'
ANY                  ')'
ANY                  ';'
ID                   'endfunction'
ID                   'code'
BLOCK                '{n     // This is some C code }}} n     void my_c_func() {n        printf("I have curly braces {} in a string!");n     }n  }'
ID                   'function'
ID                   'back_to_parsed_code'
ANY                  ';'
ID                   'endfunction'
ID                   'endclass'

您可以将模式用于目的。请注意两种模式的代码部分。YOY不能仅使用一种模式正确关闭代码部分。

lexer

lexer grammar Question_41355044Lexer;
CODE: 'code';
LCURLY: '{' -> pushMode(CODE_0);
WS:    [ trn] -> skip;
mode CODE_0;
CODE_0_LCURLY: '{' -> type(OTHER), pushMode(CODE_N);
RCURLY: '}' -> popMode;     // Close for LCURLY
CODE_0_OTHER: ~[{}]+ -> type(OTHER);
mode CODE_N;
CODE_N_LCURLY: '{' -> type(OTHER), pushMode(CODE_N);
CODE_N_RCURLY: '}' -> type(OTHER), popMode;
OTHER: ~[{}]+;

PARSER

parser grammar Question_41355044Parser;
options { tokenVocab = Question_41355044Lexer; }
skip_code: 'code' LCURLY OTHER* RCURLY;

输入

code {
   // This is some C code
   void my_c_func() {
      printf("I have curly braces {} in a string!");
   }
}

输出令牌

CODE LCURLY({) OTHER(   // Th...) OTHER({) OTHER(      pr...) 
OTHER({) OTHER(}) OTHER( in a st...) OTHER(}) OTHER() RCURLY(}) EOF

ANTLR语法解析本身使用相同的方法:https://github.com/antlr/grammars-v4/tree/master/master/antlr4

但是在那里使用运行时代码LexerAdaptor.py而不是两级模式。

相关内容

  • 没有找到相关文章

最新更新