我使用EcmaScript 5.1表达式的语法:
PrimaryExpression :
this
Identifier
Literal
ArrayLiteral
ObjectLiteral
( Expression )
FunctionExpression :
function Identifieropt ( FormalParameterListopt ) { FunctionBody }
MemberExpression :
PrimaryExpression
FunctionExpression
MemberExpression [ Expression ]
MemberExpression . IdentifierName
new MemberExpression Arguments
NewExpression :
MemberExpression
new NewExpression
CallExpression :
MemberExpression Arguments
CallExpression Arguments
CallExpression [ Expression ]
CallExpression . IdentifierName
Arguments :
( )
( ArgumentList )
LeftHandSideExpression :
NewExpression
CallExpression
我用Wirth表示法重写它,为它编写递归解析器。 我得到了什么:
PrimaryExpression = this | Identifier | Literal | ObjectLiteral | "(" ExpressionNoIn ")"
Literal = NullLiteral | BooleanLiteral | NumericLiteral | StringLiteral
ObjectLiteral = "{" [PropertyNamesAndValues] "}"
MemberExpression = ( PrimaryExpression | FunctionExpression | new MemberExpression Arguments ) MemberExpression'
MemberExpression' = ( "." Identifier | "[" Expression "]" ) MemberExpression' | e.
NewExpression = ( PrimaryExpression | FunctionExpression ) MemberExpression' | new NewExpression'
NewExpression' = MemberExpression Arguments MemberExpression' | NewExpression
CallExpression = MemberExpression Arguments CallExpression'
CallExpression' = ( Arguments | "[" Expression "]" | "." Identifier ) CallExpression' | e.
Arguments = "(" [ArgumentList] ")"
LeftHandSideExpression = NewExpression | CallExpression
所以,问题是如何在我的新语法中对规则 LeftHandSideExpression 使用左因子分解。我需要它,因为First [LeftHandSideExpression]和First [CallExpression]的交集不为空。
谢谢!
答案 0 :(得分:1)
基本思想是避免在解析中做出决定,其中2个产生和路径共享公共令牌。 所以基本上你想将终端移到制作的前面,如果它们被埋在其他非终端并共享的话。
您基本上想要分解常见令牌,并将它们放在新的非终结点中以避免非确定性选择。
EG: 如果我有这个语法:
S -> X | Y
X -> ab
Y -> ac
我必须"移动"终端" a" up,以便解析器在尝试选择是否采用X或Y时不会卡住。
解决方案如下:
S -> A'
A' -> a(X|Y)
X -> b
Y -> c
小心考虑之前可能有的所有路径,包括lambda(空字符串)。处理lambda是一种特殊情况,需要进一步处理以获得一个合适的语法(或者甚至可以反映你想要的语言)。
虽然是,但这增加了额外的非终结符号,它是一种确保确定性语法不需要超前的算法。
注意:可以使用前瞻值指定某些语言生成器(解析语法)。有时为了简单起见,这是首选,但请注意,使用超过1的前瞻,将极大地增加将包含在解析器中的前瞻表。它是N ^ k的量级,其中n是产生的数量,k是前瞻。
此网站使用我在编译器类中使用的特定表单来解释它: http://www.cs.sun.ac.za/rw711/2012term2/lectures/lec5/l5.pdf
如果不首选外部网站链接,我可以拍摄幻灯片的一些图片并将其附在此处以供将来存档。
我建议阅读语法,因为它们可以很有趣!