如何在读取字符串时保留ANTLR4中的空白?
我正在创建一个语法,它将用于创建C#的词法分析器和解析器。这将接受下面的输入并输出SQL如何在读取字符串时保留ANTLR4中的空白?,antlr4,Antlr4,我正在创建一个语法,它将用于创建C#的词法分析器和解析器。这将接受下面的输入并输出SQL (path.path.path=“如何做某事”) 目前,我使用以下方法忽略空白: WS:[\t\r\n]+->skip;//跳过空白 问题是,当我阅读引号中的内容时,我需要保留空格,因为它将用于搜索。 我该怎么做呢? 多谢各位 编辑1 以下是我当前解析字符串的尝试: TEXT : [a-zA-Z_]+; 我刚刚遇到的问题并不多,但我找不到一个我理解如何实现的解决方案 我还补充说
(path.path.path=“如何做某事”)
目前,我使用以下方法忽略空白:
WS:[\t\r\n]+->skip;//跳过空白
问题是,当我阅读引号中的内容时,我需要保留空格,因为它将用于搜索。
我该怎么做呢?
多谢各位
编辑1
以下是我当前解析字符串的尝试:
TEXT : [a-zA-Z_]+;
我刚刚遇到的问题并不多,但我找不到一个我理解如何实现的解决方案
我还补充说
@lexer::members{
//Lexer members
//Used to preserve whitespace when reading in statements
boolean ignore=true;
}
我看到过类似的东西。
其中,ignore
的值将决定是否跳过空白。我还将我的空白规则更改为:
WS : [ \t\r\n]+ {if(ignore) skip();};
但我不确定在扫描语句之前如何将ignore
设置为false
,以及在完成后如何将其更改回true
编辑2
我已复制了我的全部语法文件:
// Grammar for Search Criteria
grammar SearchGen;
@members{
//Lexer members
//Used to preserve whitespace when reading in statements
boolean ignore=true;
}
r : block_clause*
| block
| statement;
// block = ( statement CLAUSE statement )
block : OPEN_BRACKET start_segment+ end_segment CLOSE_BRACKET;
block_clause : block clause;
start_segment : statement clause;
end_segment : statement;
statement : OPEN_BRACKET path search_term CLOSE_BRACKET; //Change TEXT to allows for blah.blah="hiv"
path : TEXT '.' TEXT '.' TEXT;
clause : NOT | OR | AND | WITHIN;
search_term : OPERATOR SEARCH_TYPE;
OPEN_BRACKET : '(';
CLOSE_BRACKET : ')';
UNDERSCORE : '_';
SEARCH_TYPE : '"' (~["\\] | '\\' .)* '"';
OPERATOR : EQUALS | GREATER_THAN | LESS_THAN | AMP; //Maybe put the amp and quotes in TEXT/
GREATER_THAN : '>' | '>';
LESS_THAN : '<' | '<';
QUOTE : '"' | '&quot;';
EQUALS : '=';
AMP : '&' | '&';
NOT : 'NOT' | 'not';
OR : 'OR' | 'or';
AND : 'AND' | 'and';
WITHIN : 'WITHIN' | 'within';
//Possible problem : If a keyword that the user is looking for matches one of the above tokens
TEXT : [a-zA-Z_]+; // Include Underscore
DIGIT : [0-9]+;
// yyyy-mm-dd
DATE : YEAR'-'MONTH'-'DAY;
YEAR : [1-2][(0-9)][(0-9)][(0-9)];
MONTH : [0][1-9] | [1-9] | [1][(0-2)];
DAY : [0][1-9] | [1-2][0-9] | [3][0-1];
WS : [ \t\r\n]+ ->skip; // Skips whitespace
//搜索条件的语法
语法搜索引擎;
@成员{
//Lexer成员
//用于在读取in语句时保留空白
布尔忽略=真;
}
r:block_子句*
|挡块
|声明;
//block=(语句子句语句)
块:开括号开始括号+结束括号结束括号;
block_子句:block子句;
start_段:语句子句;
结束部分:声明;
语句:打开_括号路径搜索_术语关闭_括号//将文本更改为允许blah.blah=“hiv”
路径:文本“.”文本“.”文本;
条款:不在|或|和|内;
搜索项:操作员搜索类型;
左括号:'(';
右括号:');
下划线:''";
搜索类型:“”(~[“\\]”“\\”)*“;
运算符:等于|大于|小于| AMP;//可以将AMP和引号放在文本中/
大于:'>'.'';
小于:“所以看起来您在第一种可选的搜索类型中处理字符串,即:
SEARCH_TYPE : '"'TEXT'"'
现在,该规则的问题不是它忽略了空格,而是根本不允许使用空格,因为TEXT
与空格不匹配。因此,如果您输入类似“hello”
,您将无法获得没有空格的字符串,您将获得语法错误,因为该输入与“'TEXT”不匹配“'
模式。根据该规则,只有“hello”才是有效字符串。也不允许使用字母或下划线以外的字符,这与字符串通常的工作方式不同
大概您希望在双引号字符串中允许除双引号以外的任何内容(在大多数编程语言中,也有一些方法可以转义双引号)。所以我们可以使用一个倒排字符类,它匹配除了双引号以外的任何东西:
SEARCH_TYPE: '"' ~'"'* '"';
现在为了允许转义,我们还可以允许反斜杠后跟任何字符(包括双引号):
请注意,这也允许空字符串,而您的原始规则不允许空字符串
所以现在我们的字符串实际上可以包含空格,而不会产生语法错误。那么,我们如何防止空间被忽略呢?我们不需要,因为我们不需要<代码>WS:[\t\r\n]+->跳过
仅仅意味着如果lexer要生成一个WS
令牌,它只会跳到下一个令牌。这不会影响其他lexer规则内部发生的事情。换句话说,WS
规则跳过标记之间的空格,而不是标记内部的空格。因此,忽略空白根本不是问题
PS:您的语法还包含一个您从未使用过的引号
标记,这看起来像是一个错误。此外,年
、月
和日
规则可能应声明为片段,因为它们本身永远无法匹配。因此,看起来您在搜索类型
的第一个备选方案中处理字符串,即:
SEARCH_TYPE : '"'TEXT'"'
现在,该规则的问题不是它忽略了空格,而是根本不允许使用空格,因为TEXT
与空格不匹配。因此,如果您输入了类似于“hello”
,您将无法得到没有空格的字符串,您将得到一个语法错误,因为该输入与“'TEXT'”
模式不匹配。根据该规则,只有“hello”才是有效字符串。也不允许使用字母或下划线以外的字符,这与字符串通常的工作方式不同
大概您希望在双引号字符串中允许除双引号以外的任何内容(在大多数编程语言中,也有一些方法可以转义双引号)。所以我们可以使用一个倒排字符类,它匹配除了双引号以外的任何东西:
SEARCH_TYPE: '"' ~'"'* '"';
现在为了允许转义,我们还可以允许反斜杠后跟任何字符(包括双引号):
请注意,这也允许空字符串,而您的原始规则不允许空字符串
所以现在我们的字符串实际上可以包含空格,而不会产生语法错误。那么,我们如何防止空间被忽略呢?我们不需要,因为我们不需要<代码>WS:[\t\r\n]+->跳过
仅仅意味着如果lexer要生成一个WS
令牌,它只会跳到下一个令牌。这不会影响其他lexer规则内部发生的事情。换句话说,WS
规则跳过标记之间的空格,而不是标记内部的空格。因此,忽略空白根本不是问题
PS:您的语法还包含一个您从未使用过的引号
标记,看起来像一团雾