抑制ANTLR4贪婪(为现有DSL构建ANTLR4语法)
我已经有了一个DSL,并且想为它构建ANTLR4语法 下面是该DSL的一个示例:抑制ANTLR4贪婪(为现有DSL构建ANTLR4语法),antlr4,Antlr4,我已经有了一个DSL,并且想为它构建ANTLR4语法 下面是该DSL的一个示例: rule isC { true when O_M in [5, 6, 17, 34] false in other cases } rule isContract { true when O_C in ['XX','XY','YY'] false in other cases } rule isFixed { true when F3 ==~ '.*/.*/.*-F
rule isC {
true when O_M in [5, 6, 17, 34]
false in other cases
}
rule isContract {
true when O_C in ['XX','XY','YY']
false in other cases
}
rule isFixed {
true when F3 ==~ '.*/.*/.*-F.*/.*'
false in other cases
}
rule temp[1].future {
false when O_OF in ['C','P']
true in other cases
}
rule temp[0].scale {
10 when O_M == 5 && O_C in ['YX']
1 in other cases
}
DSL是如何通过使用已经变得一团糟的正则表达式来解析的——因此需要语法
它的工作方式如下:它提取左部分(在之前,当时)和右部分,然后由Groovy对它们进行评估
我仍然希望Groovy对其进行评估,但是使用语法组织解析过程。所以,本质上,我需要的是使用某种通配符来提取这些左右部分
不幸的是,我不知道该怎么做。以下是我到目前为止的情况:
grammar RuleDSL;
rules: basic_rule+ EOF;
basic_rule: 'rule' rule_name '{' condition_expr+ '}';
name: CHAR+;
list_index: '[' DIGIT+ ']';
name_expr: name list_index*;
rule_name: name_expr ('.' name_expr)*;
condition_expr: when_condition_expr | otherwise_condition_expr;
condition: .*?;
result: .*?;
when_condition_expr: result WHEN condition;
otherwise_condition_expr: result IN_OTHER_CASES;
WHEN: 'when';
IN_OTHER_CASES: 'in other cases';
DIGIT: '0'..'9';
CHAR: 'a'..'z' | 'A'..'Z';
SYMBOL: '?' | '!' | '&' | '.' | ',' | '(' | ')' | '[' | ']' | '\\' | '/' | '%'
| '*' | '-' | '+' | '=' | '<' | '>' | '_' | '|' | '"' | '\'' | '~';
// Whitespace and comments
WS: [ \t\r\n\u000C]+ -> skip;
COMMENT: '/*' .*? '*/' -> skip;
我将以下内容作为输出
ENTERING RULE
-- tons of text
LEAVING RULE
我如何使它不那么贪婪,所以如果我解析这个给定的输入,我将得到5条规则?贪婪来自于条件
和结果
更新:
事实证明,跳过空白并不是最好的主意,所以过了一段时间,我得出以下结论:
谢谢你的提示 不要在解析器规则中使用*?
,而是尝试使用~'}'*
以确保这些规则不会试图读取超过规则末尾的内容
此外,您可以跳过lexer中的空格,但在解析器规则中使用CHAR+
和DIGIT+
。这意味着以下各项是等效的:
true in other cases
true in other cases
规则临时[1]。未来
规则te m p[1]。f u t u r e
除此之外,在其他情况下,您将设置为单个令牌,而不是3个令牌,因此以下内容不等效:
true in other cases
true in other cases
您可能应该首先制定以下词法规则,然后制定CHAR
和DIGIT
规则fragment
规则:
ID : CHAR+;
INT : DIGIT+;
谢谢你,那是我需要的推动!我将更新答案,以包含我最后使用的语法。