如何在表驱动的解析器中使用解析表和堆栈推送映射



我正在编写一个编译器,使用自上而下的表驱动解析。我已经把我的语法转换成LL(1),如下所示:

<START> -> <prog> 
<aParams> -> <expr> <rept-aParams1> 
<aParams> -> EPSILON 
<aParamsTail> -> ',' <expr> 
<addOp> -> '+' 
<addOp> -> '-' 
<addOp> -> 'or' 
<arithExpr> -> <term> <rightrec-arithExpr> 
<arraySize> -> '[' 'intNum' ']' 
<arraySize> -> '[' ']' 
<assignOp> -> '=' 
<assignStat> -> <variable> <assignOp> <expr> 
<classDecl> -> 'class' 'id' <opt-classDecl2> '{' <rept-classDecl4> '}' ';' 
<expr> -> <arithExpr> 
<expr> -> <relExpr> 
<fParams> -> <type> 'id' <rept-fParams2> <rept-fParams3> 
<fParams> -> EPSILON 
<fParamsTail> -> ',' <type> 'id' <rept-fParamsTail3> 
<factor> -> <variable> 
<factor> -> <functionCall> 
<factor> -> 'intNum' 
<factor> -> 'floatNum' 
<factor> -> '(' <arithExpr> ')' 
<factor> -> 'not' <factor> 
<factor> -> <sign> <factor> 
<funcBody> -> <opt-funcBody0> 'do' <rept-funcBody2> 'end' 
<funcDecl> -> 'id' '(' <fParams> ')' ':' <type> ';' 
<funcDecl> -> 'id' '(' <fParams> ')' ':' 'void' ';' 
<funcDef> -> <funcHead> <funcBody> ';' 
<funcHead> -> <opt-funcHead0> 'id' '(' <fParams> ')' ':' <type> 
<funcHead> -> <opt-funcHead0> 'id' '(' <fParams> ')' ':' 'void' 
<functionCall> -> <rept-functionCall0> 'id' '(' <aParams> ')' 
<idnest> -> 'id' <rept-idnest1> '.' 
<idnest> -> 'id' '(' <aParams> ')' '.' 
<indice> -> '[' <arithExpr> ']' 
<memberDecl> -> <funcDecl> 
<memberDecl> -> <varDecl> 
<multOp> -> '*' 
<multOp> -> '/' 
<multOp> -> 'and' 
<opt-classDecl2> -> 'inherits' 'id' <rept-opt-classDecl22> 
<opt-classDecl2> -> EPSILON 
<opt-funcBody0> -> 'local' <rept-opt-funcBody01> 
<opt-funcBody0> -> EPSILON 
<opt-funcHead0> -> 'id' 'sr' 
<opt-funcHead0> -> EPSILON 
<prog> -> <rept-prog0> <rept-prog1> 'main' <funcBody> 
<relExpr> -> <arithExpr> <relOp> <arithExpr> 
<relOp> -> 'eq' 
<relOp> -> 'neq' 
<relOp> -> 'lt' 
<relOp> -> 'gt' 
<relOp> -> 'leq' 
<relOp> -> 'geq' 
<rept-aParams1> -> <aParamsTail> <rept-aParams1> 
<rept-aParams1> -> EPSILON 
<rept-classDecl4> -> <visibility> <memberDecl> <rept-classDecl4> 
<rept-classDecl4> -> EPSILON 
<rept-fParams2> -> <arraySize> <rept-fParams2> 
<rept-fParams2> -> EPSILON 
<rept-fParams3> -> <fParamsTail> <rept-fParams3> 
<rept-fParams3> -> EPSILON 
<rept-fParamsTail3> -> <arraySize> <rept-fParamsTail3> 
<rept-fParamsTail3> -> EPSILON 
<rept-funcBody2> -> <statement> <rept-funcBody2> 
<rept-funcBody2> -> EPSILON 
<rept-functionCall0> -> <idnest> <rept-functionCall0> 
<rept-functionCall0> -> EPSILON 
<rept-idnest1> -> <indice> <rept-idnest1> 
<rept-idnest1> -> EPSILON 
<rept-opt-classDecl22> -> ',' 'id' <rept-opt-classDecl22> 
<rept-opt-classDecl22> -> EPSILON 
<rept-opt-funcBody01> -> <varDecl> <rept-opt-funcBody01> 
<rept-opt-funcBody01> -> EPSILON 
<rept-prog0> -> <classDecl> <rept-prog0> 
<rept-prog0> -> EPSILON 
<rept-prog1> -> <funcDef> <rept-prog1> 
<rept-prog1> -> EPSILON 
<rept-statBlock1> -> <statement> <rept-statBlock1> 
<rept-statBlock1> -> EPSILON 
<rept-varDecl2> -> <arraySize> <rept-varDecl2> 
<rept-varDecl2> -> EPSILON 
<rept-variable0> -> <idnest> <rept-variable0> 
<rept-variable0> -> EPSILON 
<rept-variable2> -> <indice> <rept-variable2> 
<rept-variable2> -> EPSILON 
<rightrec-arithExpr> -> EPSILON 
<rightrec-arithExpr> -> <addOp> <term> <rightrec-arithExpr> 
<rightrec-term> -> EPSILON 
<rightrec-term> -> <multOp> <factor> <rightrec-term> 
<sign> -> '+' 
<sign> -> '-' 
<statBlock> -> 'do' <rept-statBlock1> 'end' 
<statBlock> -> <statement> 
<statBlock> -> EPSILON 
<statement> -> <assignStat> ';' 
<statement> -> 'if' '(' <relExpr> ')' 'then' <statBlock> 'else' <statBlock> ';' 
<statement> -> 'while' '(' <relExpr> ')' <statBlock> ';' 
<statement> -> 'read' '(' <variable> ')' ';' 
<statement> -> 'write' '(' <expr> ')' ';' 
<statement> -> 'return' '(' <expr> ')' ';' 
<statement> -> <functionCall> ';' 
<term> -> <factor> <rightrec-term> 
<type> -> 'integer' 
<type> -> 'float' 
<type> -> 'id' 
<varDecl> -> <type> 'id' <rept-varDecl2> ';' 
<variable> -> <rept-variable0> 'id' <rept-variable2> 
<visibility> -> 'public' 
<visibility> -> 'private'

使用这里的工具,我生成了一个解析表和堆栈推送映射,它们如下:

分析表:

[[0,"','","'+'","'-'","'or'","'['","'intNum'","']'","'='","'class'","'id'","'{'","'}'","';'","'floatNum'","'('","')'","'not'","'do'","'end'","':'","'void'","'.'","'*'","'/'","'and'","'inherits'","'local'","'sr'","'main'","'eq'","'neq'","'lt'","'gt'","'leq'","'geq'","'if'","'then'","'else'","'while'","'read'","'write'","'return'","'integer'","'float'","'public'","'private'","$"],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,112,112,112,112,112,112,112,112,1,1,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,1,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,111],[0,112,2,2,112,112,2,112,112,112,2,112,112,112,2,2,3,2,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,4,112,112,112,112,112,112,112,112,112,112,112,112,112,112,111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,5,6,7,112,111,112,112,112,111,112,112,112,111,111,112,111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,111,8,8,112,112,8,111,112,112,8,112,112,111,8,8,111,8,112,112,112,112,112,112,112,112,112,112,112,112,111,111,111,111,111,111,112,112,112,112,112,112,112,112,112,112,112,112],[0,111,112,112,112,10,112,112,112,112,112,112,112,111,112,112,111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,111,111,112,112,111,112,11,112,111,112,112,112,111,111,112,111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,112,12,112,112,111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,13,111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,111,15,15,112,112,15,112,112,112,15,112,112,111,15,15,111,15,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,112,16,112,112,112,112,112,17,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,16,16,112,112,112],[0,18,112,112,112,112,112,112,112,112,112,112,112,112,112,112,111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,111,25,25,111,112,21,111,112,112,20,112,112,111,22,23,111,24,112,112,112,112,112,111,111,111,112,112,112,112,111,111,111,111,111,111,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,112,112,112,112,111,112,112,112,112,26,112,112,112,112,112,112,112,112,26,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,111],[0,112,112,112,112,112,112,112,112,112,28,112,111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,111,111,112],[0,112,112,112,112,112,112,112,112,112,29,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,112,31,112,112,112,112,112,112,112,111,112,112,112,112,112,112,112,112,111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,111,111,111,111,112,112,111,112,112,32,112,112,111,112,112,111,112,112,112,112,112,112,111,111,111,112,112,112,112,111,111,111,111,111,111,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,112,34,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,111,111,111,111,35,112,111,111,112,112,112,112,111,112,112,111,112,112,112,112,112,111,111,111,111,112,112,112,112,111,111,111,111,111,111,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,112,37,112,111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,37,37,111,111,112],[0,112,111,111,112,112,111,112,112,112,111,112,112,112,111,111,112,111,112,112,112,112,112,38,39,40,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,112,112,42,112,112,112,112,112,112,112,112,112,112,112,112,112,112,41,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,44,112,112,112,112,112,112,112,112,43,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,112,46,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,47,47,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,47,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,111],[0,111,48,48,112,112,48,112,112,112,48,112,112,111,48,48,111,48,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,111,111,112,112,111,112,112,112,111,112,112,112,111,111,112,111,112,112,112,112,112,112,112,112,112,112,112,112,49,50,51,52,53,54,112,112,112,112,112,112,112,112,112,112,112,112],[0,55,112,112,112,112,112,112,112,112,112,112,112,112,112,112,56,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,112,112,112,58,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,57,57,112],[0,60,112,112,112,59,112,112,112,112,112,112,112,112,112,112,60,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,61,112,112,112,112,112,112,112,112,112,112,112,112,112,112,62,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,64,112,112,112,63,112,112,112,112,112,112,112,112,112,112,64,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,112,65,112,112,112,112,112,112,112,112,66,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,65,112,112,65,65,65,65,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,112,68,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,69,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,70,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,71,112,112,112,112,112,112,112,112,112,72,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,112,73,112,112,112,112,112,112,112,74,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,73,73,112,112,112],[0,112,112,112,112,112,112,112,112,75,76,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,76,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,112,77,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,78,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,112,79,112,112,112,112,112,112,112,112,80,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,79,112,112,79,79,79,79,112,112,112,112,112],[0,112,112,112,112,81,112,112,112,112,112,112,112,82,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,112,84,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,86,86,86,86,85,112,86,86,112,112,112,112,86,112,112,86,112,112,112,112,112,112,86,86,86,112,112,112,112,86,86,86,86,86,86,112,112,112,112,112,112,112,112,112,112,112,112],[0,87,88,88,88,112,112,87,112,112,112,112,112,87,112,112,87,112,112,112,112,112,112,112,112,112,112,112,112,112,87,87,87,87,87,87,112,112,112,112,112,112,112,112,112,112,112,112],[0,89,89,89,89,112,112,89,112,112,112,112,112,89,112,112,89,112,112,112,112,112,112,90,90,90,112,112,112,112,89,89,89,89,89,89,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,91,92,112,112,111,112,112,112,111,112,112,112,111,111,112,111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,112,94,112,112,95,112,112,112,112,93,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,94,112,95,94,94,94,94,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,112,102,112,112,111,112,112,112,112,112,111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,97,112,111,98,99,100,101,112,112,112,112,112],[0,111,103,103,111,112,103,111,112,112,103,112,112,111,103,103,111,103,112,112,112,112,112,112,112,112,112,112,112,112,111,111,111,111,111,111,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,112,106,112,112,111,112,112,112,112,111,112,112,112,112,112,112,112,112,111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,104,105,112,112,112],[0,112,112,112,112,112,112,112,112,112,107,112,111,112,112,112,112,112,111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,107,107,111,111,112],[0,111,111,111,111,112,112,111,111,112,108,112,112,111,112,112,111,112,112,112,112,112,112,111,111,111,112,112,112,112,111,111,111,111,111,111,112,112,112,112,112,112,112,112,112,112,112,112],[0,112,112,112,112,112,112,112,112,112,111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,111,111,109,110,112]]

推送地图:

{"1":[26],"2":[29,10],"4":[10,-1],"5":[-2],"6":[-3],"7":[-4],"8":[45,50],"9":[-7,-6,-5],"10":[-7,-5],"11":[-8],"12":[10,7,53],"13":[-13,-12,30,-11,23,-10,-9],"14":[5],"15":[27],"16":[32,31,-10,51],"18":[33,-10,51,-1],"19":[53],"20":[18],"21":[-6],"22":[-14],"23":[-16,5,-15],"24":[13,-17],"25":[13,47],"26":[-19,34,-18,24],"27":[-13,51,-20,-16,11,-15,-10],"28":[-13,-21,-20,-16,11,-15,-10],"29":[-13,14,17],"30":[51,-20,-16,11,-15,-10,25],"31":[-21,-20,-16,11,-15,-10,25],"32":[-16,2,-15,-10,35],"33":[-22,36,-10],"34":[-22,-16,2,-15,-10],"35":[-7,5,-5],"36":[15],"37":[52],"38":[-23],"39":[-24],"40":[-25],"41":[37,-10,-26],"43":[38,-27],"45":[-28,-10],"47":[14,-29,40,39],"48":[5,28,5],"49":[-30],"50":[-31],"51":[-32],"52":[-33],"53":[-34],"54":[-35],"55":[29,3],"57":[30,21,54],"59":[31,6],"61":[32,12],"63":[33,6],"65":[34,49],"67":[35,19],"69":[36,20],"71":[37,-10,-1],"73":[38,52],"75":[39,9],"77":[40,16],"79":[41,49],"81":[42,6],"83":[43,19],"85":[44,20],"88":[45,50,4],"90":[46,13,22],"91":[-2],"92":[-3],"93":[-19,41,-18],"94":[49],"96":[-13,8],"97":[-13,48,-38,48,-37,-16,27,-15,-36],"98":[-13,48,-16,27,-15,-39],"99":[-13,-16,53,-15,-40],"100":[-13,-16,10,-15,-41],"101":[-13,-16,10,-15,-42],"102":[-13,18],"103":[46,13],"104":[-43],"105":[-44],"106":[-10],"107":[-13,42,-10,51],"108":[44,-10,43],"109":[-45],"110":[-46]} 

解析表的结构如下所示:

On the LL(1) Parsing Table's Meaning and Construction
The top row corresponds to the columns for all the potential terminal symbols, augmented with $ to represent the end of the parse.
The leftmost column and second row are all zero filled, to accomodate the way Fischer and LeBlanc wrote their parser's handling of abs().
The remaining rows correspond to production rules in the original grammar that you typed in.
Each entry in that row maps the left-hand-side (LHS) of a production rule onto a line-number. That number is the line in which the LHS had that specific column symbol in its predict set.
If a terminal is absent from a non-terminal's predict set, an error code is placed in the table. If that terminal is in follow(that non-terminal), the error is a POP error. Else, it's a SCAN error.
POP error code = # of predict table productions + 1
SCAN error code = # of predict table productions + 2
In practice, you'd want to tear the top, label row off of the table and stick it in a comment, so that you can make sense of your table. The remaining table can be used as is.

然而,考虑到这些,我不完全确定如何进行。我只是想知道,给定这两个对象,解析令牌流并确定其语法正确的通用算法是什么。

这对您没有多大帮助,因为如下所述,为该语法生成的LL(1)解析表不准确。

然而,值得一提的是,以下是我对这些表格的逆向工程。通过阅读该工具引用的课本,您可能会对该过程有更深入的了解。(注意:链接是而不是背书,既不是书也不是供应商。我只是从工具中复制了它。)

终端符号按顺序出现在解析表的最上面一行(指令说应该删除该行以供使用)。因此,终端符号1是',',符号2是'+',依此类推,直到符号46,它是传统上用作输入标记结束的$。(这与'$'不同,后者是字面意义上的美元符号。)

非终端符号不会显式显示(因此无法从表中恢复它们的名称),但它们也按顺序编号。共有54个,解析表的每一行(前两行之后)对应于一个非终端符号。

该工具输出的预测集部分列出了110个产品(及其相应的索引)。每个生产对应于"生产"中的一个条目;"推送映射";,它(因为这是Javascript)使用生产编号的字符串转换作为密钥。

推送映射中的对应值是一个索引列表:负索引指终端,正索引指非终端。未使用索引0,这就是未使用解析映射的第0行的原因。根据这些索引,可以重建产品的右侧,但它们实际上用于指示在解析的每个步骤将什么推送到解析堆栈上。

堆栈包含当前预测列表,堆栈的顶部元素是解析中此时的即时预测。

因此算法如下:

  1. 将解析器堆栈初始化为[1, -46],这表示当前预测由生成<START> -> <prog>的右侧和输入标记$的末尾组成。

  2. 重复以下操作,直到因错误或接受而终止:

    1. 如果堆栈顶部为负数:
      • 如果前瞻性令牌具有相应的令牌编号(即栈顶的绝对值),则弹出堆栈并接受前瞻性令牌。如果该标记是输入结束指示符,则解析结束,并且输入有效。否则,新的前瞻性令牌是下一个输入令牌
      • 如果先行标记与堆栈顶部不对应,则输入不正确。报告错误并终止分析
    2. 如果堆栈顶部为正:
      • parseTable[stack.top()][lookahead]中检索值rhs。如果rhs的值大于生产数量(在这种情况下为值111或112),则输入不正确。报告错误并终止分析。(该值会告诉你是扫描错误还是弹出错误,但这可能对你没有太大区别。它可以用来改进错误报告。)
      • 弹出解析堆栈,从末尾开始将pushMap[rhs]中的元素推送到堆栈中。(例如,如果rhs是4,那么您将使用来自pushMap["4"]的列表,即[10, -1]。因此,您将首先将-1,然后将10推送到解析器堆栈上。)
      • 对于黑客工具生成的推送地图,ε右侧的推送图中似乎没有条目。因此,如果pushMap[rhs]不存在,您只需弹出解析堆栈;没有什么可推的

该算法不包括为成功解析生成语法树的任何过程。但是,如果你想做的不仅仅是决定输入是否是一个有效的程序,那么你肯定会想要生成某种语法树。


注意:语法不是LL(1),所以解析表是错误的

我不知道你应该给你正在使用的工具多大的可信度。

你的语法不是LL(1),但该工具没有提供任何关于这一事实的指示。

就是一个简单的例子

<arraySize> -> '[' 'intNum' ']' 
<arraySize> -> '[' ']' 

其中前瞻令牌CCD_ 18不预测唯一生产。通过左因子分解很容易解决这个问题,但我看不到任何证据表明该工具能够做到这一点。

一个更严重的问题是

<expr>      -> <arithExpr> 
<expr>      -> <relExpr> 
<arithExpr> -> <term> <rightrec-arithExpr> 
<relExpr>   -> <arithExpr> <relOp> <arithExpr>

由于relExpr可以从arithExpr开始,因此expr的两个乘积重叠;不可能通过对单个前瞻性令牌(或者,实际上,任何恒定数量的前瞻性令牌)的检查来预测expr是否是比较。在解析完初始算术表达式(其长度可以是任意的)之前,您无法判断。

如果你坚持LL(1),你需要做一些类似的事情:

<expr> -> <arithExpr> <optional-relExpr-tail>
<optional_relExpr-tail> -> EPSILON
<optional_relExpr-tail> -> <relop> <arithExpr>

此外,expr导致factor,其可以是variablefunctionCall,两者都以idnest开始(其最终导致终端id)。但这也不是全部,因为您可能在idnestfunctionCall中都会遇到序列<id> '(' <aParams> ')'

也许这个工具并不想告诉你你的语法不是LL(1),但在我看来,在这种情况下,它不应该生成表,因为表一定会误导你。预测冲突意味着解析表必须更喜欢一个或另一个竞争产品,而它不喜欢的产品不能出现在解析中,结果是有效的输入将被拒绝。

<意见>

我相信为这种语言创建LL(1)语法是可能的,但老实说,这似乎不是最好的策略。语法中已经有太多的非终结符,几乎读不懂。如果您坚持使用自上而下的解析器,请使用允许";扩展的";BNF:右侧的重复运算符和可选运算符。或者,您可以使用具有简化语法的LALR(1)生成器,因为LALR(2)既允许左递归,也允许左非乘子生成。

<意见>

最新更新