ANTLR解析MismatchedTokenException

2023-12-09

我正在尝试为我正在编写的更简单的语言编写一个简单的解析器。它由后缀表达式组成。到目前为止,我的解析器遇到了问题。当我在输入上运行它时2 2 * test >>我收到 MismatchedTokenException。

另外,我将如何实现递归后缀解析器?

这是我的代码:

grammar star;

options {
    language=Python;
    output=AST;
    ASTLabelType=CommonTree;
}

tokens {DECL;}
//start
//  :   decl ;
//decl
//  :   type ID -> ^(DECL type ID)
//  ;

program
    :   (body)+
    ;

body    :   (nested WS)*
    |   (var WS)*
    |   (get WS)*
    ;

var
    :   nested ID '>>'
    ;

get
    :   ID '<<'
    ;

//expressions

term
    :   INT
    ;

expr
    :   term (term operator)*
    ;

nested
    :   expr (expr operator)*
    ;

operator 
    :   ('*' | '+' | '/' | '%' | '-')
    ;

ID
    :   ('a'..'z' | 'A'..'Z') ('a..z' | '0'..'9' | 'A'..'Z')*
    ;

INT
    :   '0'..'9'+
    ;

WS
    :   (' ' | '\n' | '\t' | '\r') {$channel=HIDDEN;}
    ;

有几点是不正确的:

1

你已经把WS上的令牌HIDDEN通道,这使得它们无法用于解析器规则。所以所有WS你里面的令牌body规则不正确。

2

_(your latest edit removed the left-recursion issue, but I'll still make a point of it sorry, your other question has a left recursive rule (expr), so I'll leave this info in here)_

ANTLR 是一个LL解析器-generator,这样你就可以创建左递归语法。以下是左递归:

expr
  :  term term operator
  ;

term
  :  INT
  |  ID
  |  expr
  ;

因为第一个term在 - 的里面expr规则可能匹配expr统治自己。与任何 LL 解析器一样,ANTLR 生成的解析器无法处理左递归。

3

如果你修复了WS问题,你的body规则将产生以下错误消息:


(1/7) Decision can match input such as "INT" using multiple alternatives  

这意味着解析器无法“看到”哪个规则INT令牌所属。这是因为您所有的body替代方案可以重复零次或多次,并且expr and nested也重复。它们都可以匹配INT,这就是 ANTLR 所抱怨的。如果您删除*是这样的:

body
    :   nested
    |   var
    |   get
    ;

// ...

expr
    :   term (term operator)
    ;

nested
    :   expr (expr operator)
    ;

错误将会消失(尽管这仍然不会导致您的输入被正确解析!)。

我意识到这可能听起来仍然含糊不清,但解释起来(或者如果您对这一切还不熟悉的话,理解一下)并不简单。

4

正确考虑递归expr inside expr,你需要远离左递归,正如我在#2。你可以这样做:

expr
  :  term (expr operator | term operator)*
  ;

这仍然是不明确的,但这是在使用 LL 语法描述后缀表达式的情况下,AFAIK 不可避免的。要解决此问题,您可以在options { ... }语法部分:

options {
  language=Python;
  output=AST;
  backtrack=true;
}

Demo

如何解析递归表达式的一个小演示可能如下所示:

grammar star;

options {
  language=Python;
  output=AST;
  backtrack=true;
}

parse
  :  expr EOF -> expr
  ;

expr
  :  (term -> term) ( expr2 operator -> ^(operator $expr expr2) 
                    | term operator  -> ^(operator term term)
                    )*
  ;

expr2 
  :  expr
  ;

term
  :  INT
  |  ID
  ;

operator 
  :  ('*' | '+' | '/' | '%' | '-')
  ;

ID
  :  ('a'..'z' | 'A'..'Z') ('a..z' | '0'..'9' | 'A'..'Z')*
  ;

INT
  :  '0'..'9'+
  ;

WS
  :  (' ' | '\n' | '\t' | '\r') {$channel=HIDDEN;}
  ;

测试脚本:

#!/usr/bin/env python
import antlr3
from antlr3 import *
from antlr3.tree import *
from starLexer import *
from starParser import *

def print_level_order(tree, indent):
  print '{0}{1}'.format('   '*indent, tree.text)
  for child in tree.getChildren():
    print_level_order(child, indent+1)

input = "5 1 2 + 4 * + 3 -"
char_stream = antlr3.ANTLRStringStream(input)
lexer = starLexer(char_stream)
tokens = antlr3.CommonTokenStream(lexer)
parser = starParser(tokens)
tree = parser.parse().tree 
print_level_order(tree, 0)

产生以下输出:


-
   +
      5
      *
         +
            1
            2
         4
   3  

对应于以下 AST:

enter image description here

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ANTLR解析MismatchedTokenException 的相关文章

  • 无法在 PIL 中对 16 位 TIF 应用图像滤镜

    我尝试使用 python 应用图像过滤器PIL http www pythonware com products pil 代码很简单 im Image open fnImage im im filter ImageFilter BLUR 此
  • Python 3.4.3 tkinter - 程序在声明 IntVar 或任何其他 tkinter 数据类型时冻结

    上一主题 Python 3 4 tkinter checkbutton变量处理不起作用 响应 https stackoverflow com questions 33711472 python 3 4 tkinter checkbutton
  • Ajax 调用后使用 Django 模板呈现 JSON 对象

    我一直在尝试了解什么是最佳方法Ajax http en wikipedia org wiki Ajax 28programming 29 in Django http en wikipedia org wiki Django 28web f
  • Python 将列表中的字符串转换为数字

    我遇到了以下错误消息 以 10 为基数的 int 的文字无效 2 2 外部用单引号括起来 内部用双引号括起来 该数据位于primes列出使用print primes 0 样本数据在primes list 2 3 5 7 The primes
  • 如何在 Linux 中显示进程状态(阻塞、非阻塞)

    有没有办法查询 Linux 进程表中进程的状态 以便能够演示执行查询时进程是正在运行还是被阻止 我的目标是从进程或程序的 外部 执行此操作 因为我希望从操作系统进程的角度来理解这一点 但欢迎任何想法 这是Python代码阻塞的过程 impo
  • Python - 包和设置文件

    我有一个 python 包 需要从我的项目目录中提取设置 这是我的项目当前的结构 Project bin mypackage package files Project myproject project files start py se
  • SMTPAuthenticationError: (535, b'5.7.8 用户名和密码在 Django 生产中不被接受?

    我在 Heroku 上部署了一个 Django 应用程序 在其中一节中 我使用 SMTP Gmail 设置向用户发送电子邮件 当我在本地运行项目时 电子邮件发送成功 但在 Heroku 上部署的项目上却发送失败 我在 Stackoverfl
  • 确定Python模块中的函数是否可用

    我正在研究一些使用Python套接字的代码socket fromfd http docs python org library socket html socket fromfd功能 但是 此方法并非在所有平台上都可用 因此我正在编写一些后
  • 肥皂服务的良好框架是什么?

    我正在寻找一个用于肥皂的好框架service 我更喜欢使用Pythonic框架 但是在查看了soaplib rpclib 太不稳定 SOAPy 不适用于2 7 和ZSI 太 令人困惑 之后 我不确定这是否可能 我对使用另一种语言感到满意 尽
  • 如何使用泛型类型的构造函数

    如何使用 python 泛型类型的构造函数 T typing TypeVar T class MyClass typing Generic T def init self initialValue typing Iterable self
  • 图像堆栈的最大强度投影

    我正在尝试重新创建该功能 max array 3 来自 MatLab 它可以获取 N 个图像的 300x300px 图像堆栈 我在这里说 图像 因为我正在处理图像 实际上这只是一个大的双数组 300x300xN 并创建一个 300x300
  • 不重复的Python组合

    我有一个数字列表 我想从中进行组合 如果我有清单 t 2 2 2 2 4 c list itertools combinations t 4 结果是 2 2 2 2 2 2 2 4 2 2 2 4 2 2 2 4 2 2 2 4 但我想得到
  • 监控单个文件

    我需要监控 使用watchdog http pythonhosted org watchdog index html 单个文件 而不是整个目录 避免监视整个目录的最佳方法是什么 我想this http pythonhosted org wa
  • 多线程写入文件

    前几天刚开始使用 python 对多线程的整个概念还很陌生 我在多线程时写入文件时遇到问题 如果我按照常规方式执行此操作 它会不断覆盖正在写入的内容 使用 5 个线程写入文件的正确方法是什么 不降低性能的最佳方法是在所有线程之间使用队列 每
  • 如何替换被测模块的文件访问引用

    pyfakefs https code google com p pyfakefs 听起来非常有用 它 最初是作为核心 Python 模块的一个适度的假实现来开发的 以支持中等复杂的文件系统交互 并于 2006 年 9 月在 Google
  • Python unittest - 与assertRaises相反?

    我想编写一个测试来确定在给定情况下不会引发异常 测试是否有异常很简单is上调 sInvalidPath AlwaysSuppliesAnInvalidPath self assertRaises PathIsNotAValidOne MyO
  • 在 Django/python 中,如何将内存缓存设置为无限时间?

    cache set key value 9999999 但这并不是无限的时间 def get memcache timeout self timeout Memcached deals with long gt 30 days timeou
  • 避免在列表理解中计算相同的表达式两次[重复]

    这个问题在这里已经有答案了 我在列表理解中使用一个函数和一个 if 函数 new list f x for x in old list if f x 0 令我恼火的是这个表达f x 在每个循环中计算两次 有没有办法以更清洁的方式做到这一点
  • Networkx 中 Louvain 分区的可视化

    请帮助我更改 Louvain 聚类算法结果的可视化 我从网站上获取了代码https github com taynaud python louvain https github com taynaud python louvain我可以重写
  • Tensorflow ctc_loss_calculator:找不到有效路径

    当运行我的神经网络 双向 LSTM 进行音频识别时 我使用连接主义时间分类 CTC 但在某些时候 训练网络时我几乎每批都会收到来自 Tensorflow 的警告 W tensorflow core util ctc ctc loss cal

随机推荐

  • 如何在 Python 中解释离散傅里叶变换 (FFT) 的结果

    关于这个主题有很多问题 我已经循环浏览了其中很多问题 获得了有关处理频率的概念性指导 here and here 有关 numpy 函数的文档 here 有关提取幅度和相位的操作信息 here 并走出站点 例如this or this 然而
  • 如何在 C# 中将行筛选的 DataGridView 设置为 DataTable

    我有 DataGridview 我过滤了其中的一些行 我需要将新数据源保存到新的 DataTable 由于某种原因我当前的代码不起作用 这里我如何尝试转换它 LogGridView DataSource as DataTable Defau
  • 通过子项无限嵌套 ngFor

    我发现了一些关于 Angular2 中嵌套 ngFor 循环的问题 但不是我正在寻找的问题 我想在列表中显示类别 我的 JSON 看起来像这样 Categories Title Categorie A Children Title Sub
  • 如何检索 LoaderExceptions 属性?

    我在更新服务参考时收到错误消息 自定义工具警告 无法加载一种或多种请求的类型 检索 LoaderExceptions 属性以获取更多信息 如何检索 LoaderExceptions 属性 Update 当我重新导入域对象项目时 我的错误消失
  • 在张量流中将 1 通道掩模应用于 3 通道张量

    我正在尝试将掩码 二进制 仅一个通道 应用于 RGB 图像 3 个通道 标准化为 0 1 我当前的解决方案是 我将 RGB 图像分割成它的通道 将其与蒙版相乘 然后再次连接这些通道 with tf variable scope apply
  • CodeIgniter 的 CAS 身份验证库

    我正在尝试在 CodeIgniter 应用程序中实现 CAS 身份验证 但我找不到当前是否有为其设置的库 我通过只包含类并添加一些肮脏的修复来进行管理 但如果有人知道合适的库 我认为这将是一个更干净的解决方案 我一直在浏览这里以及谷歌上的一
  • PHP:帮助处理此日期格式

    我正在使用 CodeIgniter 构建一个应用程序 我的 SQL Server 数据库中有包含日期 时间字段的记录 我正在从 m d Y 文本字段中输入的日期查询这些记录 这对应于数据库中的日期格式 不幸的是我在英国 所以我想输入日期 例
  • 如何在创建新计时器之前检查计时器是否处于活动状态

    我在另一个线程上遇到了这个计时器代码 当您按下RaisedButton同时进行多次 每次点击都会增加 1 秒 从而增加减少的速度 有关检查计时器是否已处于活动状态以及是否不让计时器处于活动状态的最简单方法的任何想法RaisedButton创
  • 如何从私有 Docker 注册表中删除镜像?

    我运行一个私人 docker 注册表 我想删除除latest来自存储库 我不想删除整个存储库 只想删除其中的一些图像 这API docs没有提到做到这一点的方法 但肯定有可能吗 目前您无法使用注册表 API 来执行该任务 它只允许您删除存储
  • wamp上安装magento的问题

    大家好 谁能帮我解决安装 magento 时遇到的问题 我的问题是我已经在 wamp 上下载了 magento 在安装过程中我收到了错误 它给出的消息是致命错误 超过了 60 秒的最大执行时间 c wamp www magento lib
  • signalr 我如何从服务器向呼叫者发布消息

    我正在使用 Signalr 1 1 4 因为我仍在使用 net4 所以无法升级到 signalr 2 基本上我想从服务器向调用者发布消息 以避免消息发送到任何未启动进程的客户端 我的集线器类看起来像这样 public class Updat
  • VBScript 中的文件名字符串空格问题

    当我运行此命令时出现错误 但我不确定原因 运行 VBScript 来执行 bat 文件 我想将任何错误消息输出到日志文件 为此 我有以下代码 Set WshShell CreateObject WScript Shell WshShell
  • 如何过滤 Quickblox 用户?

    我想根据应用程序用户的电话号码或电子邮件过滤他们 但我不希望完全匹配 而是用户应返回的部分电子邮件或部分号码作为响应 Quickblox iOS SDK 有办法吗 假设我有一些 Quickblox 用户 如下所示 ID NAME Email
  • Swift 类中的静态与类函数/变量?

    以下代码在 Swift 1 2 中编译 class myClass static func myMethod1 class func myMethod2 static var myVar1 func doSomething myClass
  • 素数生成器逻辑

    我应该去上课PrimeNumberGenerator其中有一个方法nextPrime这将打印出用户输入的数字之前的所有质数 Ex Enter a Number 20 2 3 5 7 11 13 17 19 我们的老师告诉我们应该使用嵌套fo
  • VBScript“类型不匹配”问题与“[in, out] BSTR *”参数

    我正在使用第三方 COM 对象 该对象的一些方法将值作为 BSTR 指针传回 由于 VBscript 仅支持 Variant 类型 尝试以类似 Object Method sMyString 的方式使用会合理地以 类型不匹配 错误结束 我怀
  • 如何使用切换添加和删除必需的属性

    我的用户可以访问表单 为了简化任务 我放置了一个可选择的列表 但如果答案不在列表中 他们可以手动添加原因 默认情况下需要选择列表 但如果用户访问文本字段 则该文本字段将成为必需的 并且不再需要该列表 反之亦然 HTML div class
  • Spark / Scala:使用最后一次观察进行前向填充

    使用 Spark 1 4 0 Scala 2 10 我一直在试图找出一种方法来用最后一个已知的观察结果转发填充空值 但我没有看到一个简单的方法 我认为这是一件很常见的事情 但找不到显示如何执行此操作的示例 我看到用值向前填充 NaN 的函数
  • 上一个片段在新片段下方可见

    我有一个带有 ViewPager 的 TabLayout ViewPager 有四个片段 F1 F2 F3 和 F4 F1 包含一个 FrameLayout 它可以有 2 个片段 F11 和 F12 最初 我使用以下代码在 FrameLay
  • ANTLR解析MismatchedTokenException

    我正在尝试为我正在编写的更简单的语言编写一个简单的解析器 它由后缀表达式组成 到目前为止 我的解析器遇到了问题 当我在输入上运行它时2 2 test gt gt 我收到 MismatchedTokenException 另外 我将如何实现递