0

惊喜,我正在为一个项目构建一个类似于 SQL 的语言解析器。

我让它大部分时间都在工作,但是当我开始根据它要处理的真实请求对其进行测试时,我意识到它在内部的行为与我想象的不同。

以下语法中的主要问题是我为语言关键字' pct_within '定义了一个词法分析器规则PCT_WITHIN。这很好用,但如果我尝试匹配像“ attributes.pct_vac ”这样的字段,我会得到具有“ attributes.ac ”文本的字段和一个漂亮的 ANTLR 错误:

line 1:15 mismatched character u'v' expecting 'c'

语法

grammar Select;

options {
  language=Python;
}

eval returns [value]
    : field EOF 
    ;

field returns [value]
    : fieldsegments {print $field.text}
    ;

fieldsegments
    : fieldsegment (DOT (fieldsegment))*
    ;

fieldsegment
    : ICHAR+ (USCORE ICHAR+)*
    ;

WS                      : ('\t' | ' ' | '\r' | '\n')+ {self.skip();};

ICHAR                   : ('a'..'z'|'A'..'Z');

PCT_CONTAINS            : 'pct_contains';

USCORE                  : '_';
DOT                     : '.';

我一直在阅读有关该主题的所有内容。即使是错误的,Lexer 如何在发现内容时使用它。如何使用语义预测来消除歧义/如何使用前瞻。但是我阅读的所有内容都没有帮助我解决这个问题。

老实说,我不明白这怎么可能是一个问题。我一定遗漏了一些非常明显的东西,因为我看到的其他语法有像EXISTS这样的 Lexer 规则,但这不会导致解析器采用像“ existsOrNot ”这样的字符串并用“ rNot ”的文本吐出和IDENTIFIER

我错过了什么或做错了什么?

4

1 回答 1

1

将您的字段段解析器规则转换为词法分析器规则。就目前而言,它将接受像这样的输入

"abc      
_     abc"

这可能不是你想要的。该规则不会匹配关键字“pct_contains”,因为它是单独定义的。如果您想接受某些序列中的关键字作为常规标识符,则必须将其包含在接受的标识符规则中。

于 2013-06-01T10:24:28.997 回答