第一步:使用Actipro SyntaxEditor中的LL(*)解析器。不过,这可以应用于任何LL(k)解析器。
我目前正在尝试为Javascript编写一个有效的LL(k)语法(使用ECMA-262参考),有时计算左递归是可以的,但我在计算这个问题的解决方案时遇到了困难。(可能已经失去了注意力,因为我已经连续工作了三天了)
好的,解决方案示例:
按照这个规则:
BitwiseORExpression :
BitwiseXORExpression
BitwiseORExpression | BitwiseXORExpression
它将变成:
expBitwiseOR.Production = expBitwiseXOR | expBitwiseOR + @bitwiseOrSign + expBitwiseXOR;
和避免左递归:
expBitwiseOR.Production = expBitwiseXOR + ( @bitwiseOrSign + expBitwiseXOR ).ZeroOrMore();
很简单。然而,我被更复杂的规则所困扰,例如:
MemberExpression :
PrimaryExpression
FunctionExpression
MemberExpression [ Expression ]
MemberExpression . IdentifierName
new MemberExpression Arguments
我已经尝试了几种方法,其中一些是有效的(即它们"有效",但不是应该的),而大多数是无效的(即左递归)。老实说,我不希望得到一个完整的答案或完整的解决方案,但也许有人会想到如何用这样一个复杂的规则或其他东西来避免这个问题。
也不需要将其放入Actipro Parser的正确语法中,任何模拟代码都会有所帮助!
由于这些事情经常发生,在拼命询问后不久,你就会在吃三明治时得到答案。TL;DR:解决方式如下:
expMemberExpression.Production =
(
expPrimaryExpression
|stFunctionExpression
| (@NewKeyword + expMemberExpression + expArguments)
) + expMemberExpressionHelper.ZeroOrMore();
expMemberExpressionHelper.Production = (symLiteralOpenSquare + expExpression + symLiteralCloseSquare)
| ( @punctuator + symIdentifier );