AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 79294110
Accepted
Yevgeniy P
Yevgeniy P
Asked: 2024-12-19 19:30:03 +0800 CST2024-12-19 19:30:03 +0800 CST 2024-12-19 19:30:03 +0800 CST

如何强制在规则中对非终端符号使用相同的生成式?

  • 772

假设我有一个 ANTLR 语法:

program = word (' ' word)*
  ;

word = 'dog' | 'cat' | 'bird'
  ;

据我了解,它将匹配上述任何单词序列,例如“dog dog cat”、“dog cat bird cat”等。但如果我只想匹配相同值的重复,例如“dog dog”、“cat cat cat cat”、“bird bird bird”等,该如何修改上述语法来做到这一点?

换句话说,我希望“program”规则中重复出现的非终端符号“word”始终匹配相同的生成规则,而不是为“word”指定的任何规则,但不必在“program”规则中明确列出它们中的每一个(例如,如果“word”有大量的替代方案),这意味着我想避免这样的事情:

program:
    'dog' (' ' 'dog')*
  | 'cat' (' ' 'cat')*
  | 'bird' (' ' 'bird')*
  ...
  ;

我认为在正则表达式中,这是使用反向引用(例如“\1”)实现的,在 ANTLR 语法中是否有等效的实现,或者有其他方法可以实现?

parsing
  • 1 1 个回答
  • 53 Views

1 个回答

  • Voted
  1. Best Answer
    Bart Kiers
    2024-12-20T20:45:09+08:002024-12-20T20:45:09+08:00

    正如 kaby76 所述:在解析器规则中处理此问题意味着引入谓词,这意味着在语法中添加特定于目标的代码(通常不建议这样做)。这可能看起来像这样(使用 Java 目标):

    grammar P;
    
    
    @parser::members {
      boolean sameTokenAhead() {
        Token previous = _input.LT(-1);
        Token next = _input.LT(1);
        return previous.getType() == next.getType();
      }
    }
    
    parse
     : repeated_words* EOF
     ;
    
    repeated_words
     : word ( {sameTokenAhead()}? word )*
     ;
    
    word
     : DOG
     | CAT
     | BIRD
     ;
    

    请注意,上例中的词法分析器会丢弃空格。解析bird dog dog dog cat cat将产生以下解析树:

    '- parse
       |- repeated_words
       |  '- word
       |     '- 'bird' (BIRD)
       |- repeated_words
       |  |- word
       |  |  '- 'dog' (DOG)
       |  |- word
       |  |  '- 'dog' (DOG)
       |  '- word
       |     '- 'dog' (DOG)
       |- repeated_words
       |  |- word
       |  |  '- 'cat' (CAT)
       |  '- word
       |     '- 'cat' (CAT)
       '- '<EOF>'
    

    另一种可能性是从这些重复的单词中创建一个单独的标记:

    DOG
     : 'dog' (' ' 'dog')*
     ;
    

    或者仅匹配您在问题中提到的一个或多个单词:

    program
     : word (' ' word)*
     ;
    
    word
     : 'dog' | 'cat' | 'bird'
     ;
    

    然后在解析之后,检查监听器是否相同,word如果不相同,则可能引发错误。

    • 2

相关问题

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

  • 从 Type::new() 调用函数

  • 是否有可能将某个值提升到 Grammar TOP?

  • 如何使用 XPath/CSS 获取名称以冒号开头的属性的值/内容?

  • 用于识别指数符号数字和标识符的 ANTLR 语法

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    为什么这个简单而小的 Java 代码在所有 Graal JVM 上的运行速度都快 30 倍,但在任何 Oracle JVM 上却不行?

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    何时应使用 std::inplace_vector 而不是 std::vector?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Marko Smith

    我正在尝试仅使用海龟随机和数学模块来制作吃豆人游戏

    • 1 个回答
  • Martin Hope
    Aleksandr Dubinsky 为什么 InetAddress 上的 switch 模式匹配会失败,并出现“未涵盖所有可能的输入值”? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge 为什么这个简单而小的 Java 代码在所有 Graal JVM 上的运行速度都快 30 倍,但在任何 Oracle JVM 上却不行? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini 具有指定基础类型但没有枚举器的“枚举类”的用途是什么? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer 何时应使用 std::inplace_vector 而不是 std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB 为什么 GCC 生成有条件执行 SIMD 实现的代码? 2024-02-17 06:17:14 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve