如何编写 ANTLR4 语法来解析匹配的 html 标签

问题描述 投票:0回答:1

我编写了一个简单的解析器来尝试了解 ANTLR4 如何在具有匹配标签的 HTML 风格语言上工作。例如,如果有一个标签

<p> ... </p>

我觉得应该匹配一个规则:

p: '<' 'p' CLASS_NAME? '>' tag_block '<' '/' 'p' '>' ;

这看起来相当繁重,因为如果每个规则可以包含其他所有内容,我必须以这种方式手动编写每个规则。是否有一种通用的方法来编写规则,即对于可以包含其他标签的每种标签,前后的尖括号必须匹配?或者我只需为每个人写一个:

p: '<' 'p' CLASS_NAME? '>' tag_block '<' '/' 'p' '>' ;
div: '<' 'div' CLASS_NAME? '>' tag_block '<' '/' 'div' '>' ;
canvas: '<' 'canvas' CLASS_NAME? '>' tag_block '<' '/' 'canvas' '>' ;

是否可以编写通用复合标签,例如:

compoundtag: '<' ('p' | 'div' | 'canvas') CLASS_NAME? '>' tag_block '<' '/' ( MATCHING EARLIER NAME???) '>'

我确信我犯了更多错误,所以这里是完整的语法文件:

grammar simple_grail;

prog: tag_block ;

tag_block: (tag)*;

/* root definition of any tag in Grail */
tag:
    p | div | canvas | rect | button | txt | textlit;

p: '<' 'p' CLASS_NAME? '>' tag_block '<' '/' 'p' '>' ;
div: '<' 'div' CLASS_NAME? '>' tag_block '<' '/' 'div' '>' ;
canvas: '<' 'canvas' CLASS_NAME? '>' tag_block '<' '/' 'canvas' '>' ;
rect:
     '<' 'rect' CLASS_NAME?
     'x' ASSIGN_COORD 'y' ASSIGN_COORD 'w' ASSIGN_COORD 'h' ASSIGN_COORD
     '/>' ;
button:
    '<' 'button' (CLASS_NAME)? (NAME)? 'text' ASSIGN_TEXT '/>' ;
txt:
    '<' 'text' 'x' ASSIGN_COORD 'y' ASSIGN_COORD '/>' ;

textlit:
    TEXT?
    ;

CLASS_NAME: [a-zA-Z_] [a-zA-Z_0-9]* ;

ASSIGN_COORD: '=' [0-9]+ ;

name: 'name' '=' NAME ;

NAME: [A-Za-z_][A-Za-z_0-9]* ;

ASSIGN_TEXT: '=' ('"' [^"]* '"' | '\'' [^']* '\'');

TEXT: [^<]+ ;

我想解析第一个小程序:

<p>text goes here</p>

我希望 textlit 应该与文本匹配,对于像 p 这样围绕文本的标签, 我应该覆盖 exitTextlit() 方法和 exitP() 来决定要做什么。如果我截取了 EnterP(),那么里面还没有文本。是这样吗?

有一个警告说我可以匹配空字符串,我知道如果我跳过空格会产生错误,但我不明白程序应该如何匹配:

<p></p>

如果textlit不能为空。

parsing antlr4
1个回答
0
投票

(至少)有两件事出了问题:

  1. textlit
    不应匹配空字符串,因为
    textlit
    正在被
    tag_block: (tag)*;
  2. 重复
  3. ANTLR 的正则表达式语法略有不同:不要执行
    [^<]+
    (匹配一个或多个字符
    '^'
    '<'
    ),而是执行以下操作:
    ~[<]+
    (匹配除
    '<'
    之外的一个或多个字符) )

修复这些点后,您将看到为输入创建以下标记

<p>text goes here</p>

5 tokens:
  1    null                           '<'
  2    TEXT                           'p>text goes here'
  3    null                           '<'
  4    TEXT                           '/p>'
  5    EOF                            '<EOF>'

如您所见,

p>text goes here
不正确。解决这个问题的一种方法是使用“词法模式”。您可以在 ANTLR 存储库中查看 HTML 语法:https://github.com/antlr/grammars-v4/tree/master/html

© www.soinside.com 2019 - 2024. All rights reserved.