【发布时间】:2022-01-23 04:23:09
【问题描述】:
在过去的几个月里,在本网站成员的帮助下,我已经能够编写(第一阶段)一个 Lexer 和 Parser 来将 Lang X 翻译成 Java。因为我是这个主题的新手,所以我选择了一个简单的逐行解析器,现在它能够在 15 分钟内解析大约 1000 个语言文件,并且出现少量错误/异常和大约 1M 行代码,问题被隔离到源文件而不是解析器。为了更好的表达,我将其称为平面解析。
现在进入第 2 阶段,即转换为 Java。像任何语言一样,我的有数据结构、过程、子例程等,我认为最好从下面更改解析器(为简单起见,我专注于数据结构(称为 TABLE)):
// Main entry point of the program
program
: executableUnit+ EOF
;
// Execution units (line by line)
executableUnit:
| itemBlockStart
| itemBlockEnd
| itemStatement
| tableHeader
;
itemBlockStart: BEGIN;
itemBlockEnd: END;
tableHeader: // A TABLE declaration statement
TABLE atom LETTER (atom)*
;
// Item statement
itemStatement:
// Tables with Item statements
ITEM atom+
// Base atom lowest of the low
atom:
MINUS? INT #IntegerAtom
| REAL_FORMAT #RealAtom
| FIX_POINT #FixPointAtom
| (MINUS | EQUALS)? NAME DOT? #NameAtom
| LETTER #LetterAtom
| keywords DOT? #KeywordAtom
| DOLLAR atom DOLLAR #DollarAtom
| hex_assign #HexItem
;
到这里:
// Execution units (by structure)
executableUnit:
tableStatement
| itemStatement
;
// Table statement, header and body
tableStatement:
tableHeader (itemBlockStart | itemBlockEnd | itemStatement)*;
在我们继续之前,TABLE 和单独的 ITEM 语句可以出现在代码中的任何地方,它们自己(Java 输出将是公共的)或在过程中(Java 输出将是私有的)
想象一下,当解析器产生相同数量的错误,但解析输入的时间要长 10 倍时,我会感到沮丧(如果你愿意的话)。在选择正确的道路方面,我有点理解增加的时间段。我对小组的问题是:
- 有没有办法强制解析器提前关闭 TABLE 结构以减少时间段?
- 具有这种逻辑树结构分组是否值得增加时间?
我希望朝这个方向发展的愿望是有一个带有迷你树的 Listener 回调,其中所有相关项目都可以访问。 IE。如果过程语句中的迷你树不在 Java 中是公共的。
【问题讨论】:
-
随着你的变化,语法模棱两可。解析器无法轻易确定 tableStatement 何时结束以及下一个 executableUnit 何时开始。我认为在解析错误时,会有一连串的回溯,剥离一个 itemStatement,重试并再次失败,然后再一次。尝试添加语义谓词来阻止 itemStatement 上的贪婪 * 运算符。实际上是一个有趣的例子,我需要在语法分析中注意和测试。
标签: performance parsing grouping antlr4