【问题标题】:ANTLR4- dynamically inject tokenANTLR4-动态注入令牌
【发布时间】:2013-08-12 01:57:05
【问题描述】:

所以我正在编写一个python解析器,我需要根据python grammar specification动态生成INDENTDEDENT标记(因为python不使用显式分隔符)。

基本上我有一堆表示缩进级别的整数。在INDENT 标记中的嵌入式Java 操作中,我检查当前缩进级别是否高于堆栈顶部的级别;如果是,我推它;如果没有,我打电话给skip()

问题是,如果当前缩进级别与堆栈中的多个级别匹配,我必须生成多个 DEDENT 标记,我不知道该怎么做。

我当前的代码:(注意within_indent_blockcurrent_indent_level在别处管理)

fragment DENT: {within_indent_block}? (SPACE|TAB)+;

INDENT: {within_indent_block}? DENT
        {if(current_indent_level > whitespace_stack.peek().intValue()){
                 whitespace_stack.push(new Integer(current_indent_level));
                 within_indent_block = false;
         }else{
                 skip();
         }
         }
         ;    

DEDENT: {within_indent_block}? DENT
        {if(current_indent_level < whitespace_stack.peek().intValue()){
            while(current_indent_level < whitespace_stack.peek().intValue()){
                      whitespace_stack.pop();
                      <<injectDedentToken()>>; //how do I do this
            }
         }else{
               skip();
         }
         }
         ;

我该怎么做和/或有更好的方法?

【问题讨论】:

    标签: parsing antlr4


    【解决方案1】:

    您发布的代码存在一些问题。

    1. INDENTDEDENT 规则在语义上相同(考虑谓词和规则引用,但忽略操作)。由于INDENT 首先出现,这意味着您永远不会拥有由DEDENT 规则生成的令牌,即这种语法。
    2. {within_indent_block}? 谓词出现在您引用 DENT 之前以及 DENT 片段规则本身内部。这种重复没有任何作用,但会减慢您的词法分析器。

    匹配后操作的实际处理最好放在Lexer.nextToken() 的覆盖中。例如,您可以从以下内容开始。

    private final Deque<Token> pendingTokens = new ArrayDeque<>();
    
    @Override
    public Token nextToken() {
        while (pendingTokens.isEmpty()) {
            Token token = super.nextToken();
            switch (token.getType()) {
            case INDENT:
                // handle indent here. to skip this token, simply don't add
                // anything to the pendingTokens queue and super.nextToken()
                // will be called again.
                break;
    
            case DEDENT:
                // handle indent here. to skip this token, simply don't add
                // anything to the pendingTokens queue and super.nextToken()
                // will be called again.
                break;
    
            default:
                pendingTokens.add(token);
                break;
            }
        }
    
        return pendingTokens.poll();
    }
    

    【讨论】:

      猜你喜欢
      • 2017-03-12
      • 1970-01-01
      • 1970-01-01
      • 2021-12-22
      • 2023-02-05
      • 1970-01-01
      • 1970-01-01
      • 2022-12-09
      • 1970-01-01
      相关资源
      最近更新 更多