You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ANTLR解析Shell命令报错:Mismatched input 'echo 1'问题求助

问题描述

我编写了用于解析Shell命令的ANTLR语法,具体定义如下:

grammar cmdline;

command     : call | pipe | command ';' command;
pipe        : call '|' call
            | pipe '|' call ;

call : WS? (redirection WS?)* argument (WS? atom)* WS? ;
atom : redirection | argument ;
redirection : '<' WS? argument
            | '>' WS? argument ;
argument : (quoted | UNQUOTED)+ ;

quoted : singleQuoted
       | doubleQuoted
       | backQuoted ;
singleQuoted: '\'' NONNEWLINEANDNONSINGLEQUOTE* '\'' ;
backQuoted  : '`' NONNEWLINEANDNONBACKQUOTE* '`' ;
doubleQuoted: '"' (backQuoted | DOUBLEQUOTECONTENT)* '"' ;


// Lexer rules
WS : [ \t\r\n]+ ;
UNQUOTED : (~[ '"`\r\n|;><])+ ;
NONNEWLINEANDNONSINGLEQUOTE : (~[\n\r'])+ ;
NONNEWLINEANDNONBACKQUOTE : (~[\n\r`])+ ;
DOUBLEQUOTECONTENT : (~[\n\r"`])+ ;

尝试解析命令echo 1时,出现错误:

line 1:0 mismatched input 'echo 1' expecting {'<', '>', ''', '`', '"', WS, UNQUOTED}.

我认为echo应匹配argument规则,1应匹配atom规则,无法理解错误产生的原因,调整Lexer规则顺序也未解决问题,恳请帮助。


问题分析与解决

你的语法核心问题是ANTLR语法符号书写错误,导致Lexer无法正确拆分token:

1. HTML实体转义字符无效

ANTLR语法不支持HTML实体(如"、<、>),必须直接使用对应的ASCII字符:

  • 替换"为"(或在字符串中用\"转义)
  • 替换&lt;为<,&gt;为>

2. UNQUOTED规则错误包含空格

原规则中因&quot;无效,导致Lexer无法识别空格为排除字符,最终把echo 1整个字符串当成单个UNQUOTED token,而非拆分为echo、空格、1三个独立token。

修正后的语法

grammar cmdline;

command     : call | pipe | command ';' command;
pipe        : call '|' call
            | pipe '|' call ;

call : WS? (redirection WS?)* argument (WS? atom)* WS? ;
atom : redirection | argument ;
redirection : '<' WS? argument
            | '>' WS? argument ;
argument : (quoted | UNQUOTED)+ ;

quoted : singleQuoted
       | doubleQuoted
       | backQuoted ;
singleQuoted: '\'' NONNEWLINEANDNONSINGLEQUOTE* '\'' ;
backQuoted  : '`' NONNEWLINEANDNONBACKQUOTE* '`' ;
doubleQuoted: '"' (backQuoted | DOUBLEQUOTECONTENT)* '"' ;


// Lexer rules
WS : [ \t\r\n]+ ;
UNQUOTED : (~[ '"\`\r\n|;<>])+ ;
NONNEWLINEANDNONSINGLEQUOTE : (~[\n\r'])+ ;
NONNEWLINEANDNONBACKQUOTE : (~[\n\r`])+ ;
DOUBLEQUOTECONTENT : (~[\n\r"`])+ ;

验证效果

修正后解析echo 1时,Lexer会正确生成三个token:UNQUOTED(echo)、WS(空格)、UNQUOTED(1),Parser会按照call -> argument (WS atom)的规则匹配,不会再出现语法错误。


内容的提问来源于stack exchange,提问作者Maestro Maestro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 12:57:13