Antlr能否忽略部分关键字?仅改语法实现非s=xxx规则过滤
Answer
Absolutely! You can achieve this solely by modifying your ANTLR grammar (no additional custom code needed). Here's a step-by-step adjustment to your existing rules that will filter out all non-s=... clauses and simplify the AST exactly as you requested:
Modified Grammar
// Core expression rules (adjusted to filter valid clauses) expr : factor ( (AND | OR)^ factor )* ; factor : valid_ava | NOT^ factor | (LPAREN! expr RPAREN!) | invalid_ava! ; // Only match valid `s=...` clauses (case-insensitive if needed) valid_ava : key=('s'|'S') EQUALS value=ALPHANUM ; // Catch all other `key=value` clauses and mark them to be excluded from AST invalid_ava : key=ALPHANUM EQUALS value=ALPHANUM ; // Existing token rules (unchanged except optional case-insensitive s) AND : ('and' | 'AND'); OR : ('or' | 'OR'); NOT : ('not' | 'NOT'); EQUALS : '='; // Added this missing token from your original snippet! ALPHANUM : (ALPHA | DIGIT | LIMITED_SYMBOLS)+ ; WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\f' )+ { $channel = HIDDEN; } ; fragment ALPHA : ('a'..'z' | 'A'..'Z') ; fragment DIGIT : '0'..'9' ; fragment LIMITED_SYMBOLS : ('.' | '!' | '@' | '#' | '$' | '%' | '^' | '&' | '*' | '-' | '_' | '+' | '~' | ':' | '/' | '?' | '|');
Key Changes Explained
Split
avainto valid/invalid rules:valid_avaexplicitly matches onlys=...(orS=...for case-insensitivity) — this rule generates AST nodes we want to keep.invalid_avacatches all otherkey=valuepairs, and the!suffix tells ANTLR to exclude this entire rule from the AST (effectively ignoring it).
Adjust
factorrule:- We keep the valid
valid_ava, NOT operator, and parenthesized expressions (with brackets excluded from AST as before). - The
invalid_ava!entry ensures any non-s=...factor is stripped from the AST entirely.
- We keep the valid
Preserve logical structure:
- The
exprrule maintains your original logical operator (AND/OR) hierarchy, but since invalid factors are removed, it only connects valids=...clauses.
- The
Test Case Results
For your input example:
a=10 AND s=1 AND s=2 or ((a=9 AND s=1) AND s=2)
The resulting AST will be exactly what you want:
- First branch:
s=1 AND s=2(thea=10clause is ignored) - Second branch:
((s=1) AND s=2)(thea=9clause is ignored, parentheses structure preserved)
Edge Cases to Note
- If an expression has no valid
s=...clauses (e.g.,a=1 AND b=2), the AST will be empty — you may want to handle this in your parser logic if needed, but it’s outside the scope of grammar-only changes. - The NOT operator will still apply to valid factors (e.g.,
NOT s=5becomesNOT^ s=5in the AST) — if you want to ignore NOT as well, just changeNOT^ factortoNOT^ factor!.
内容的提问来源于stack exchange,提问作者toy
相关产品推荐
相关产品推荐

