【问题标题】:Markup parser failing标记解析器失败
【发布时间】:2012-11-29 19:10:20
【问题描述】:

对于我尝试解析的标记语言,我决定尝试使用 ANTLR 生成解析器。我是这个领域的新手,我搞砸了。

我的语法是

grammar Test;
DIGIT   :   ('0'..'9');
LETTER  :   ('A'..'Z');
SLASH   :   '/'; 
restriction
    :   ('E' ap)
    |   ('L' ap)
    |   'N';
ap  :   LETTER LETTER LETTER;
car :   LETTER LETTER;
fnum    :   DIGIT DIGIT DIGIT DIGIT? LETTER?;
flt :   car fnum?;
message :   'A' (SLASH flt)? (SLASH restriction)?;

当我给它一个输入字符串A/KK543/EPOS 时,这正是我想要的。但是,当我给它A/KL543/EPOS 时,它失败了(MismatchedTokenException(9!=5))。这似乎是某种冲突;它想在第一个 L 上生成restriction,所以似乎我在语言定义中做错了什么,但我无法正确找出是什么。

【问题讨论】:

    标签: antlr antlr3 parser-generator


    【解决方案1】:

    对于输入 "A/KK543/EPOS",创建以下标记:

    'A' 'A'
    斜线'/'
    字母“K”
    字母“K”
    数字'5'
    数字'4'
    数字'3'
    斜线'/'
    'E' 'E'
    字母“P”
    字母“O”
    字母“S”

    但是对于输入"A/KL543/EPOS",这些是创建的:

    'A' 'A'
    斜线'/'
    字母“K”
    '二'
    数字'5'
    数字'4'
    数字'3'
    斜线'/'
    'E' 'E'
    字母“P”
    字母“O”
    字母“S”

    如您所见,字符 'L' 确实没有被标记为 LETTER。对于解析器规则中的文字标记'A''E''L''N',ANTLR(自动)创建单独的词法分析器规则,这些规则放置在所有其他词法分析器规则之前。这会使您的词法分析器在幕后看起来像这样:

    A      : 'A';
    E      : 'E';
    L      : 'L';
    N      : 'N';
    DIGIT  : '0'..'9';
    LETTER : 'A'..'Z';
    SLASH  : '/'; 
    

    因此,任何单个'A''E''L''N' 都不会成为LETTER 令牌。这就是 ANTLR 的工作原理。如果您想将它们作为字母进行匹配,您需要创建一个解析器规则letter 并让 it 也匹配这些标记。像这样的:

    message
     : A (SLASH flt)? (SLASH restriction)?
     ;
    
    flt
     : car fnum?
     ;
    
    fnum
     : DIGIT DIGIT DIGIT DIGIT? letter?
     ;
    
    restriction
     : E ap
     | L ap
     | N
     ;
    
    ap
     : letter letter letter
     ;
    
    car
     : letter letter
     ;
    
    letter
     : A
     | E
     | L
     | N
     | LETTER
     ;
    
    A      : 'A';
    E      : 'E';
    L      : 'L';
    N      : 'N';
    DIGIT  : '0'..'9';
    LETTER : 'A'..'Z';
    SLASH  : '/'; 
    

    它将像这样解析输入"A/KL543/EPOS"

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-19
      相关资源
      最近更新 更多