我正在创建一个语法,该语法将用于为C#创建词法分析器和解析器。这将采用以下输入并输出SQL。
(path.path.path="how to do something")
此刻,我通过以下方式忽略空格:
WS : [ \t\r\n]+ -> skip; // Skips whitespace
问题是,当我阅读引号中的内容时,我需要保留空格,因为它将在搜索中使用。 我该怎么做呢? 谢谢。
编辑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
答案 0 :(得分:1)
因此,看起来您在SEARCH_TYPE
的第一个替代方案中处理了字符串,即:
SEARCH_TYPE : '"'TEXT'"'
现在,该规则的问题不在于它忽略空格-就是因为TEXT
与空格不匹配,根本不允许使用空格。因此,如果您输入类似" hello "
的内容,则没有空格就不会得到字符串,您会收到语法错误,因为该输入与'"'TEXT'"'
模式不匹配。根据该规则,只有“ hello”是有效的字符串。除字母或下划线外,也不允许使用其他字符,这与字符串通常的工作方式不同。
大概您想在双引号字符串中允许除双引号之外的任何内容(并且在大多数编程语言中,也有某种转义双引号的方法)。因此,我们可以只使用与双引号之外的任何字符匹配的反向字符类:
SEARCH_TYPE: '"' ~'"'* '"';
现在允许转义,我们还可以允许在反斜杠后加上任何字符(包括双引号):
SEARCH_TYPE: '"' (~["\\] | '\\' .)* '"';
请注意,这还允许使用空字符串,而您的原始规则则不允许。
所以现在我们的字符串实际上可以包含空格而不会产生语法错误。那么如何防止空格被忽略呢?我们不是因为我们不需要。 WS : [ \t\r\n]+ ->skip;
只是意味着如果词法分析器要生成WS
令牌,它只会跳到下一个令牌。这不会影响其他词法分析器规则内部发生的情况。换句话说:WS
规则会跳过标记之间的空格 ,而不是 inside 标记。因此,忽略空格根本不是问题。
PS:您的语法还包含一个您从未使用过的QUOTE
令牌,这看起来像是一个错误。此外,YEAR
,MONTH
和DAY
规则可能应该声明为片段,因为它们永远无法单独匹配。