gpt4 book ai didi

java - Antlr v4 我可以忽略不匹配的输入吗?

转载 作者:行者123 更新时间:2023-11-30 09:10:01 25 4
gpt4 key购买 nike

我试图让解析器识别度量单位,然后根据需要使用监听器转换单位。但是,当解析测试句子时,当解析器在文本的其他部分(例如单词中间)看到单元时,我会得到一个 missing matched input 错误。这是我的代码的简化版本。

UnitsOfMeasure.g4

grammar UnitsOfMeasure;

import
ImperialUnitsParser;

/*------------------------------------------------------------------
* UNITS OF MEASURE PARSER RULES
*------------------------------------------------------------------*/
include_metric_units
: imperial_types
| include_metric_units imperial_types
;

imperial_types
: i_area
;

i_area
: QUANTITY square_inch
| QUANTITY square_feet
| QUANTITY square_mile
| QUANTITY square_yard
;

/*------------------------------------------------------------------
* UNITS OF MEASURE - LEXER RULES
*------------------------------------------------------------------*/
SQUARE
: [S|s]'quare'
| [S|s]'q' '.'?
;

SQUARED
: [S|s]'quared'
| '^2'
| '<sup>2</sup>'
| '&#178'
| '\u00B2'
;

fragment PLURAL
: 's' ?
| 'es' ?
;

QUANTITY
: '-'? FLOAT
| '-'? DIGITS
;

FLOAT
: DIGITS '.' DIGITS
;

fragment DIGITS
: DIGIT+
;

fragment DIGIT
: '0'..'9'
;

/*------------------------------------------------------------------
* SKIP EVERYTHING ELSE
*------------------------------------------------------------------*/
EVERYTHING
: . -> skip
;

ImperialUnitsParser.g4

parser grammar ImperialUnitsParser;

import ImperialUnitsLexer;

/*------------------------------------------------------------------
* AREA
*------------------------------------------------------------------*/
square_inch
: SQUARE INCH
| INCH SQUARED
;

/*------------------------------------------------------------------
* LENGTH
*------------------------------------------------------------------*/
inch
: INCH
;

ImperialUnitsLexer.g4

lexer grammar ImperialUnitsLexer;

/*------------------------------------------------------------------
* BASE UNITS
*------------------------------------------------------------------*/
INCH
: [I|i]'nch' PLURAL
| [I|i]'n' '.'?
;

转换.java

public static String includeMetricUnits(String parse) throws UnitsOfMeasureParserRuntimeException
{
StringBuilder builder = new StringBuilder(parse);

ANTLRInputStream in = new ANTLRInputStream(builder.toString());
UnitsOfMeasureLexer lexer = new UnitsOfMeasureLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);

UnitsOfMeasureParser parser = new UnitsOfMeasureParser(tokens);
parser.addParseListener(new UnitsOfMeasureParseListener(builder));
parser.addErrorListener(new UnitsOfMeasureErrorListener());
parser.include_metric_units(0);
return builder.toString();
}

因此,此处的监听器会在解析流时对构建器进行一些编辑。一个工作示例如下:

“具有 1550 平方英寸书写空间的白板” 返回:

“一 block 1550 英寸2(1 米2)书写空间的白板”

但是,当我通过添加多个单元使其变得更复杂时,它会报告以下内容:

line 1:44 mismatched input 'in' expecting {EOF, QUANTITY}

在:

“具有 1550 平方英寸书写空间的白板和 775 平方英寸的触摸屏” 返回:

“具有 1550 英寸2(1 米2)书写空间的白板和 775 平方英寸的触摸屏”

在调试器之后,它执行第一次转换而没有错误,然后在它向前看后退出。我可能还没有完全正确地理解递归部分,但本质上,语法应该一直寻找,直到找到一个数量后跟一个度量单位。如果数量后面没有可识别的单位,它应该忽略它并继续。

从错误中我可以看到它在“书写”中拾取了“in”,因为我有一个 Lexer 规则将其识别为英寸,但因为没有数量,它会引发错误。

任何人都可以帮助我解决这个问题,以便我可以获得语法来忽略不匹配的输入吗?谁能告诉我递归位是否正确,以便它一直持续到句子结尾。

最佳答案

当您不想匹配作为另一个词的一部分的标记 INCH 时,您将需要匹配词,并跳过这些词:

WORD
: [a-zA-Z]+ -> skip
;

请务必将此规则放在 您的 INCH 规则之后,否则它也会将输入的 "in" 作为单词匹配(你显然不想要)。您还需要扩展此规则匹配的字符:仅 ascii 字母是不够的。

此外,[I|i] 也匹配管道字符:改为执行 [Ii]

虽然正确:

include_metric_units
: imperial_types
| include_metric_units imperial_types
;

它更像是 LR/Bison 风格。更具可读性的是写:

include_metric_units
: imperial_types+
;

要匹配可能在 token 流中但与您的任何产品都不匹配的 token ,只需匹配顶级规则中的任何 token :

parse
: ( include_metric_units // match metrics
| . // or any "dangling" single token
)* // zero or more times
EOF // end of the input
;

include_metric_units
: imperial_types+
;

是的,这是正确的:生产/解析器规则中的 . (DOT) 匹配单个标记,而不是单个字符。它只匹配词法分析器规则中的单个字符。

当我现在解析输入时

A whiteboard with 1550 square inches of writing space, and 
a touchscreen measuring 775 square inches and an in at the end...

(注意最后的 'in'!),我得到以下解析树:

enter image description here

关于java - Antlr v4 我可以忽略不匹配的输入吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22717130/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com