【问题标题】:ANTLR Grammar - Parsing labels and instructionsANTLR Grammar - 解析标签和指令
【发布时间】:2012-02-13 13:50:27
【问题描述】:

我正在编写一个使用指令列表代码的解释器。当我尝试为带有标签的指令编写语法时遇到了一些问题。

我想解析这个代码块:

LD 4
ST A
LD A
EQ 4
ST _AUX_1
(* IF *)
LDN _AUX_1
JMPC _label_2 
(* THEN *)
LD B
EQ 3
ST _AUX_2
_label_2: (* ELSE *)
_label_1: (* END IF*)
LD TRUE

如您所见,这些标签在一行中没有说明,但我必须解析的语言允许一行中的“标签+指令”。所以,指令和标签的组合有三种不同的类型:

  1. 说明
  2. 标签:
  3. 标签:说明

我可以解析 1 和 2,但我无法解析所有不同的组合。

这是我的 ANTLR 语法的摘录:

program_il : instruction* ;

instruction 
        : ID':' // label
        | ID_INST operand
        ;

operando
    : ID
    | CTE_INT
    | CTE_BOOL
    ;

我尝试将语法更改为:

instruction : (ID':')? instruction? ;

但我有下一个错误:

As a result, alternative(s) 2 were disabled for that input
[14:43:49] error(201): Analizador.g:131:29: The following alternatives can never be matched: 2

有人可以帮我解决这个问题吗? 提前谢谢你。

【问题讨论】:

    标签: parsing antlr grammar


    【解决方案1】:

    因为您现在接受Label: Instruction,所以语法不明确。解析器无法区分:

    lbl:
    LD 4
    

    lbl: LD 4
    

    换句话说,您需要让您的instructions 用某种分隔符分隔。如以下演示所示,换行符可以解决问题:

    grammar T;
    
    program_il
     : NL* instruction (NL+ instruction)* NL* EOF
     ;
    
    instruction 
     : ID ':' (ID_INST operand)?
     | ID_INST operand
     ;
    
    operand
     : ID
     | CTE_INT
     | CTE_BOOL
     ;
    
    CTE_BOOL
     : 'TRUE'
     | 'FALSE'
     ;
    
    ID_INST
     : 'LD'
     | 'ST'
     | 'EQ'
     | 'LDN'
     | 'JMPC'
     ;
    
    ID
     : ('_' | 'a'..'z' | 'A'..'Z') ('_' | 'a'..'z' | 'A'..'Z' | '0'..'9')*
     ;
    
    CTE_INT
     : ('0'..'9')+
     ;
    
    NL
     : '\r'? '\n'
     | '\r'
     ;
    
    COMMENT
     : '(*' .* '*)' {skip();}
     ;
    
    SPACE
     : (' ' | '\t')+ {skip();}
     ;
    

    现在解析输入:

    (* IF *)
    JMPC _label_2 
    (* THEN *)
    LD B
    ST _AUX_2
    _label_2: LDN _AUX_1 (* ELSE *)
    _label_1: (* END IF*)
    LD TRUE
    

    将产生以下树:

    【讨论】:

    • +1 但是,虽然我不熟悉 ANTLR,但我认为执行“指令:(ID ':')?ID_INST 操作数;”会更干净。
    • @500-InternalServerError,唉,这不适用于 ANTLR :)。对于 LL 解析器,在最左侧有可选规则通常是个好主意。
    • 哦,我知道 - 它一定是 LL(1) :)
    • 谢谢。你说得对,NL 分隔符使一切正常;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-18
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-02
    相关资源
    最近更新 更多