[解决] 在Edit3下面的底部
我目前正在开发一种新的语法(从我无法改变的某些要求),以下要求带来了问题,我现在无法解决。我正在使用Antlr4和C#目标。
语法如下:
print [blabla ]
因此括号内的所有内容都被视为字符串。所以这也是:
print [3 + 2]
将打印
3 + 2
现在我有lexer规则,显然会将3作为整数匹配。那么如何创建一个解析器规则来解析任何东西直到找到']'?我目前有以下产品:
control
:
| Print expr
| Print LeftBracket printArg RightBracket
;
我面临的问题是左括号并不总是启动一个字符串。有时(例如在while中)条件也在括号中。我想到只接受每个Lexer规则,直到到达RightBracket,然后在我使用生成的解析树时在运行时生成字符串,但在我看来非常烦人,我需要稍后插入空格,这将是困难的。 / p>
如果你需要我语法的更多部分,请在评论中提问,我会向你提供更多细节 亲切的问候
的Lukas
编辑:有关我的语法的更多信息: 以下生产使用括号:
Print LeftBracket printArg RightBracket
Repeat IntegerConstant LeftBracket body RightBracket
While LeftBracket expr RightBracket LeftBracket body RightBracket
If expr LeftBracket body RightBracket LeftBracket body RightBracket
SetPos LeftBracket IntegerConstant IntegerConstant RightBracket
EDIT2: 所以我尝试使用这些模式,但是我从它们返回时遇到了问题。这些是关于模式的代码行:
mode printMode;
WhitespacePrint
: [ \t]+
-> skip
;
LeftBracketPrint : '[' -> popMode, pushMode(stringMode);
NotLeftBracket : ~'[' -> popMode;
mode stringMode;
String : ~']'+;
RightBracketPrint: ']' -> popMode;
我在Print lexer规则中添加了pushMode(printMode)(匹配关键字) 现在解析print [1 + 2]会创建一个包含括号内整个字符串的令牌。现在当我使用print 1 + 2(应该输出3)时,我得到一个没有可行的替代ar输入'print1'异常,因为'1'有一种NotLeftBracket类型。如何在不消耗输入的情况下切换模式?
EDIT3: 接下来我尝试使用一些内联代码并使用lookahead,最终解决了我的问题:
mode printMode;
LeftBracketPrint : [ \t]+ '[' -> popMode, pushMode(stringMode);
WhitespacePrint
: [ \t]+ {_input.La(1) != '['}?
-> skip, popMode
;
mode stringMode;
String : ~']'+;
RightBracketPrint: ']' -> popMode;
答案 0 :(得分:3)
我首先将括号内的所有内容视为词法分析器中的BracketLiteral
。
LeftBracket : '[' -> pushMode(BracketLiteralMode);
mode BracketLiteralMode;
BracketLiteral : ~']'+;
RightBracket : ']' -> popMode;
在确定如何处理特殊情况之前,我会列举BracketLiteral
规则的异常在语法中出现的最后可能性。如果您可以添加这些详细信息,我可以就如何处理这些案例提出一些建议。
答案 1 :(得分:1)
如果我理解正确,在解释括号内容时存在二元性,它可以是字符串或表达式,具体取决于上下文(对于打印,它是一个字符串)。
2可能有风险:
我认为第一种方法更容易,因为在第二种方法中你必须为print内容编写解析规则,这可能无法解析:
print [ a ++++ 2 ]