问:
How to use a parse table and stack push map in a table driven parser?
I'm writing a compiler, using top-down table-driven parsing. I've converted my grammar into LL(1), and it's the following:

```<code><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'
</code>```

Using the tool here, I've generated a parse table and stack push map, which are the following:

Parse Table:

```<code>[[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]]
</code>```

Push map:

```<code>{"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]}
</code>```

The construction of the parsing table is given as the following:

```<code>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.
</code>```

Given these, though, I'm not entirely sure how to proceed. I'm just curious what the general algorithm, given the two objects, would be to parse over a stream of tokens and determine it's syntactically correct.

答:
This won't help you much because, as noted below, LL(1) parse tables generated for that grammar cannot be accurate.

However, for what it's worth, here's my reverse engineering of those tables. It's probable that you could get a deeper understanding of this procedure by reading the text book referenced by the tool. (Note: link is not an endorsement, neither of the book nor of the vendor. I just copied it from the tool.)

The terminal symbols appear in order in the top row of the parse table (the one which the instructions say should be removed for use). So terminal symbol 1 is ',', symbol 2 is '+', and so on up to symbol 46, which is the $ conventionally used as an end-of-input marker. (That's different from '$', which would be a literal dollar sign.)

Non-terminal symbols don't appear explicitly (so you can't recover their names from the tables) but they are also numbered in order. There are 54 of them, and each row of the parse table (after the first two) corresponds to a non-terminal symbol.

There are 110 productions, which are listed (with their corresponding index) in the Predict set section of the output from that tool. Each production corresponds to one entry in the "push map", which (since this is Javascript) uses the string conversion of the production number as a key.

The corresponding value in the push map is a list of indices: negative indices refer to terminals and positive indices refer to non-terminals. The index 0 is not used, which is why row 0 of the parse map is unused. From these indices, it is possible to reconstruct the right-hand side of the production, but they are actually used to indicate what to push onto the parse stack at each step in the parse.

The stack contains the list current predictions, with the top element of the stack being the immediate prediction at this point in the parse.

So the algorithm is as follows:

Initialise the parser stack to [1, -46], which indicates that the current prediction consists of the right-hand side of the production <START> -> <prog> followed by the end-of-input marker $.

Repeat the following until terminated by an error or by acceptance:

If the top of the stack is negative:

If the lookahead token has the corresponding token number (that is, the absolute value of the stack top), then pop the stack and accept the lookahead token. If that token is the end-of-input indicator, then the parse is finished and the input was valid. Otherwise, the new lookahead token is the next input token.

If the lookahead token does not correspond with the top of the stack, then the input is incorrect. Report an error and terminate the parse.

If the top of the stack is positive:

Retrieve the value rhs from parseTable[stack.top()][lookahead]. If rhs has a value greater than the number of productions (in this case, the values 111 or 112) then the input is incorrect. Report an error and terminate the parse. (The value will tell you whether it was a scan error or a pop error, but that might not make much difference to you. It could be used to improve error reporting.)

Pop the parse stack, and push the elements from pushMap[rhs] onto the stack, starting at the end. (For example, if rhs were 4, you would use the list from pushMap["4"], which is [10, -1]. So you would push first -1 and then 10 onto the parser stack.)

For the push-map generated by the hacking-off tool, it appears that there will be no entry in the pushMap for ε right-hand sides. So if pushMap[rhs] doesn't exist, you just pop the parse stack; there is nothing to push.

That algorithm does not include any procedure for producing a syntax tree for successful parses. But if you want to do anything more than just decide whether the input is a valid program or not, then you will definitely want to produce some kind of syntax tree.

Note: The grammar is not LL(1) so the parse tables are wrong.

I don't know how much credibility you should give the tool you are using.

Your grammar is not LL(1), but the tool does not provide any indication of that fact.

A simple example is

```<code><arraySize> -> '[' 'intNum' ']'
<arraySize> -> '[' ']'
</code>```

where the lookahead token [ does not predict a unique production. That would be easy to fix by left-factoring, but I don't see any evidence that the tool is capable of doing that.

A more serious problem is

```<code><expr>      -> <arithExpr>
<expr>      -> <relExpr>
<arithExpr> -> <term> <rightrec-arithExpr>
<relExpr>   -> <arithExpr> <relOp> <arithExpr>
</code>```

Since a relExpr can start with arithExpr, the two productions for expr overlap; it's not possible to predict from an examination of a single lookahead token (or, indeed, any constant number of lookahead tokens) whether the expr is a comparison or not. You can't tell until you finish parsing the initial arithmetic expression (which could have an arbitrary length).

If you insist on LL(1), you would need to do something like:

```<code><expr> -> <arithExpr> <optional-relExpr-tail>
<optional_relExpr-tail> -> EPSILON
<optional_relExpr-tail> -> <relop> <arithExpr>
</code>```

Moreover, expr leads to factor, which could be either a variable or a functionCall, both of which start with idnest (which ultimately leads to the terminal id). But that's not the whole story either, because you might encounter the sequence <id> '(' <aParams> ')' both in idnest and in functionCall.

Perhaps that tool doesn't intend to tell you that your grammar is not LL(1), but it seems to me like it should not generate tables in that case, since the tables are necessarily misleading. The prediction conflicts mean that the parsing table must prefer one or another competing production, and whichever one it does not prefer cannot appear in a parse, with the result that valid inputs will be rejected.

<opinion>

I believe that it is possible to create an LL(1) grammar for that language, but honestly it does not seem to me to be the best strategy. There are already so many book-keeping non-terminals in the grammar that it verges on the unreadable. If you insist on a top-down parser, use a generator which allows "extended" BNF: repetition and optionality operators on the right-hand side. Alternatively, you can use an LALR(1) generator with a much-simplified grammar, since LALR(1) allows both left-recursion and left-unfactored productions.

</opinion>

Body:
I'm writing a compiler, using top-down table-driven parsing. I've converted my grammar into LL(1), and it's the following:

<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'

Using the tool here, I've generated a parse table and stack push map, which are the following:

Parse Table:

[[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]]

Push map:

{"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]}

The construction of the parsing table is given as the following:

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.

Given these, though, I'm not entirely sure how to proceed. I'm just curious what the general algorithm, given the two objects, would be to parse over a stream of tokens and determine it's syntactically correct.

Body:
This won't help you much because, as noted below, LL(1) parse tables generated for that grammar cannot be accurate.

However, for what it's worth, here's my reverse engineering of those tables. It's probable that you could get a deeper understanding of this procedure by reading the text book referenced by the tool. (Note: link is not an endorsement, neither of the book nor of the vendor. I just copied it from the tool.)

The terminal symbols appear in order in the top row of the parse table (the one which the instructions say should be removed for use). So terminal symbol 1 is ',', symbol 2 is '+', and so on up to symbol 46, which is the $ conventionally used as an end-of-input marker. (That's different from '$', which would be a literal dollar sign.)

Non-terminal symbols don't appear explicitly (so you can't recover their names from the tables) but they are also numbered in order. There are 54 of them, and each row of the parse table (after the first two) corresponds to a non-terminal symbol.

There are 110 productions, which are listed (with their corresponding index) in the Predict set section of the output from that tool. Each production corresponds to one entry in the "push map", which (since this is Javascript) uses the string conversion of the production number as a key.

The corresponding value in the push map is a list of indices: negative indices refer to terminals and positive indices refer to non-terminals. The index 0 is not used, which is why row 0 of the parse map is unused. From these indices, it is possible to reconstruct the right-hand side of the production, but they are actually used to indicate what to push onto the parse stack at each step in the parse.

The stack contains the list current predictions, with the top element of the stack being the immediate prediction at this point in the parse.

So the algorithm is as follows:

Initialise the parser stack to [1, -46], which indicates that the current prediction consists of the right-hand side of the production <START> -> <prog> followed by the end-of-input marker $.

Repeat the following until terminated by an error or by acceptance:

If the top of the stack is negative:

If the lookahead token has the corresponding token number (that is, the absolute value of the stack top), then pop the stack and accept the lookahead token. If that token is the end-of-input indicator, then the parse is finished and the input was valid. Otherwise, the new lookahead token is the next input token.

If the lookahead token does not correspond with the top of the stack, then the input is incorrect. Report an error and terminate the parse.

If the top of the stack is positive:

Retrieve the value rhs from parseTable[stack.top()][lookahead]. If rhs has a value greater than the number of productions (in this case, the values 111 or 112) then the input is incorrect. Report an error and terminate the parse. (The value will tell you whether it was a scan error or a pop error, but that might not make much difference to you. It could be used to improve error reporting.)

Pop the parse stack, and push the elements from pushMap[rhs] onto the stack, starting at the end. (For example, if rhs were 4, you would use the list from pushMap["4"], which is [10, -1]. So you would push first -1 and then 10 onto the parser stack.)

For the push-map generated by the hacking-off tool, it appears that there will be no entry in the pushMap for ε right-hand sides. So if pushMap[rhs] doesn't exist, you just pop the parse stack; there is nothing to push.

That algorithm does not include any procedure for producing a syntax tree for successful parses. But if you want to do anything more than just decide whether the input is a valid program or not, then you will definitely want to produce some kind of syntax tree.

Note: The grammar is not LL(1) so the parse tables are wrong.

I don't know how much credibility you should give the tool you are using.

Your grammar is not LL(1), but the tool does not provide any indication of that fact.

A simple example is

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

where the lookahead token [ does not predict a unique production. That would be easy to fix by left-factoring, but I don't see any evidence that the tool is capable of doing that.

A more serious problem is

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

Since a relExpr can start with arithExpr, the two productions for expr overlap; it's not possible to predict from an examination of a single lookahead token (or, indeed, any constant number of lookahead tokens) whether the expr is a comparison or not. You can't tell until you finish parsing the initial arithmetic expression (which could have an arbitrary length).

If you insist on LL(1), you would need to do something like:

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

Moreover, expr leads to factor, which could be either a variable or a functionCall, both of which start with idnest (which ultimately leads to the terminal id). But that's not the whole story either, because you might encounter the sequence <id> '(' <aParams> ')' both in idnest and in functionCall.

Perhaps that tool doesn't intend to tell you that your grammar is not LL(1), but it seems to me like it should not generate tables in that case, since the tables are necessarily misleading. The prediction conflicts mean that the parsing table must prefer one or another competing production, and whichever one it does not prefer cannot appear in a parse, with the result that valid inputs will be rejected.

<opinion>

I believe that it is possible to create an LL(1) grammar for that language, but honestly it does not seem to me to be the best strategy. There are already so many book-keeping non-terminals in the grammar that it verges on the unreadable. If you insist on a top-down parser, use a generator which allows "extended" BNF: repetition and optionality operators on the right-hand side. Alternatively, you can use an LALR(1) generator with a much-simplified grammar, since LALR(1) allows both left-recursion and left-unfactored productions.

</opinion>


来源: stackexchange

问:
Swift app crashes when I call method from dependecy project (framework)
I'm trying to create a modular architecture in my project but I came across a very strange error.

I have a project called Application and another called Core.

In "Application" I have a storyboard that has a HomeViewController which imports Core.

In the ViewDidLoad of HomeViewController I have a custom button called btnLater of type RGButton which is declared inside of the Core project.

Xcode's Autocomplete recognizes the public methods when I type "self.btnLater." or "RGButton."

RGButton class on Core proejct:

```<code>public class RGButton: UIButton {

// corner radius
public func borderRadius(radius : CGFloat) {
    self.layer.cornerRadius = radius
}
...
</code>```

HomeViewController ViewDidLoad() on Application project

```<code>...
self.btnLater.layer.cornerRadius = 4
self.btnLater.borderRadius(radius: 4.0)
...
</code>```

So when I run the project... on the line

self.btnLater.layer.cornerRadius = 4

there is no crash... But on the line

self.btnLater.borderRadius(radius: 4.0)

it crashes with the following error:

Thread 1: EXC_BAD_ACCESS (code=257, address=0x1a258656e61)

I fear that some project configuration may be causing this.. but I need some light to help me figure out what the aliens are doing to my project...

Thanks in advance!

答:
I found out what the problem was... So everyone who is refactoring their project to a modular one pay attention when you use UI objects on storyboard... you have to change the Module to Core (in my case)

And make sure all Bundle.main in your project points to Bundle(identifier: "indetifier.of.framework")

ContentLicense: CC BY-SA 4.0

Body:
I'm trying to create a modular architecture in my project but I came across a very strange error.

I have a project called Application and another called Core.

In "Application" I have a storyboard that has a HomeViewController which imports Core.

In the ViewDidLoad of HomeViewController I have a custom button called btnLater of type RGButton which is declared inside of the Core project.

Xcode's Autocomplete recognizes the public methods when I type "self.btnLater." or "RGButton."

RGButton class on Core proejct:

public class RGButton: UIButton {

// corner radius
public func borderRadius(radius : CGFloat) {
    self.layer.cornerRadius = radius
}
...

HomeViewController ViewDidLoad() on Application project

...
self.btnLater.layer.cornerRadius = 4
self.btnLater.borderRadius(radius: 4.0)
...

So when I run the project... on the line

self.btnLater.layer.cornerRadius = 4

there is no crash... But on the line

self.btnLater.borderRadius(radius: 4.0)

it crashes with the following error:

Thread 1: EXC_BAD_ACCESS (code=257, address=0x1a258656e61)

I fear that some project configuration may be causing this.. but I need some light to help me figure out what the aliens are doing to my project...

Thanks in advance!


问:
Where is the System.Windows.Forms.Integration namespace?
I can't seem to find it, trying to keyboard input in a wpf form spawned from a winforms form.  Found this: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/442782b1-00a1-4e2e-9cc6-ae99b6699126/ But when I try to use it, VS2008 complains about not being able to find the System.Windows.Forms.Integration namespace.  I couldn't find a reference in the add references.  </p>

<p>The only thing I can think of it maybe because it was a VS2005 project ported to VS2008?  </p>

答:
Use newer:

```<code>%ProgramFiles(x86)%\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\WindowsFormsIntegration.dll
</code>```

ContentLicense: CC BY-SA 2.5

Body:
I can't seem to find it, trying to keyboard input in a wpf form spawned from a winforms form.  Found this: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/442782b1-00a1-4e2e-9cc6-ae99b6699126/ But when I try to use it, VS2008 complains about not being able to find the System.Windows.Forms.Integration namespace.  I couldn't find a reference in the add references.

The only thing I can think of it maybe because it was a VS2005 project ported to VS2008?

Body:
Use newer:

%ProgramFiles(x86)%\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\WindowsFormsIntegration.dll


问:
jQuery UI add droppable event listener while hovering
I want to add droppable event listener while dragging one object and hovering droppable object.

Here is my code:

```<code>$('.will-be-drag').draggable({
    helper: 'clone',
    drag: function (event, ui) {
        $('.will-be-drop').hover(function () {
            $(this).droppable({
                drop: function (event, ui) {
                    let item = ui.draggable;
                    console.log(item[0])
                    item.detach().appendTo($(this));
                }
            });
        }, function () {
            $(this).droppable('disable');
        });

    }
});
</code>```

And my HTML is like that:

```<code><div class="will-be-drag"></div>
<div class="will-be-drag"></div>
<div class="will-be-drag"></div>

<?php
for($i = 0; $i <= 3000; $i++){
?>
    <div class="will-be-drop"></div>
<?php
}
?>
</code>```

I'm doing that because of performance issues. I have 3k droppable object and it's freezing while dragging. It must add droppable eventlistener with only dragging $('.will-be-drag') object and hovering $('.will-be-drop').

With this code It only adds while hover not while dragging.

How can I do it?

I want javascript to breathe, it's being late when setting 3k droppable objects. There are only 30-40 draggable element. It's a table.

答:
Here is a Hover example:

$(function() {
  $("#draggable").draggable();
  $("#droppable").droppable({
    drop: function(event, ui) {
      $(this)
        .find("p")
        .html("Dropped!");
    }
  }).hover(function(e) {
    // IN
    $(this)
      .addClass("ui-state-highlight");
  }, function(e) {
    // OUT
    $(this)
      .removeClass("ui-state-highlight");
  });
});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>#draggable {
  width: 100px;
  height: 100px;
  padding: 0.5em;
  float: left;
  margin: 10px 10px 10px 0;
}

#droppable {
  width: 150px;
  height: 150px;
  padding: 0.5em;
  float: left;
  margin: 10px;
}</code>```

<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">

Drag me to my target

Drop here

```
</div>
</div>
</p>

<p>You can see that when you mouse over the droppable, it highlights. When you drag, it doesn't. I suspect the <code>hover</code> event cannot bubble up over the persistent <code>mousedown</code> event.</p>

<p>Would suggest this:</p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>$(function() {
  function makeDrops(n) {
    var t = $(".ui-widget").eq(1);
    for (var i = 1; i <= n; i++) {
      $("<div>", {
        id: "drop-" + i,
        class: "will-be-drop ui-widget-content"
      }).appendTo(t);
    }
  }

  function inViewport(element, detectPartial) {
    element = $(element);
    detectPartial = (!!detectPartial); // if null or undefined, default to false

    var viewport = $(window),
      vpWidth = viewport.width(),
      vpHeight = viewport.height(),
      vpTop = viewport.scrollTop(),
      vpBottom = vpTop + vpHeight,
      vpLeft = viewport.scrollLeft(),
      vpRight = vpLeft + vpWidth,

      elementOffset = element.offset(),
      elementTopArea = elementOffset.top + ((detectPartial) ? element.height() : 0),
      elementBottomArea = elementOffset.top + ((detectPartial) ? 0 : element.height()),
      elementLeftArea = elementOffset.left + ((detectPartial) ? element.width() : 0),
      elementRightArea = elementOffset.left + ((detectPartial) ? 0 : element.width());

    return ((elementBottomArea <= vpBottom) && (elementTopArea >= vpTop)) && ((elementRightArea <= vpRight) && (elementLeftArea >= vpLeft));
  }

  function markVisible(c) {
    c.each(function(i, el) {
      if (inViewport(el, true)) {
        $(el).addClass("visible");
      }
    });
  }

  makeDrops(3000);

  $(".will-be-drop").droppable({
    drop: function(event, ui) {
      let item = ui.draggable;
      console.log("Drag Item " + item.text().trim() + " dropped to " + $(this).attr("id"));
      item.detach().appendTo($(this));
    },
    over: function() {
      $(this).addClass("ui-state-highlight");
    },
    out: function() {
      $(this).removeClass("ui-state-highlight");
    }
  }).droppable("disable");

  $('.will-be-drag').draggable({
    helper: 'clone',
    start: function(e, ui) {
      markVisible($(".will-be-drop"));
      $(".will-be-drop.visible").droppable("enable");
    },
    drag: function(e, ui) {
      $(".will-be-drop.visible").droppable("disable").removeClass("visible");
      markVisible($(".will-be-drop"));
      $(".will-be-drop.visible").droppable("enable");
    },
    stop: function(e, ui) {
      $(".will-be-drop").droppable("disable");
      $(".will-be-drop.ui-state-highlight").removeClass("ui-state-highlight");
    }
  });
});</code>```

.will-be-drag {
  width: 50px;
  height: 50px;
  padding: 0.25em;
  float: left;
  margin: 10px 10px 10px 0;
}

.will-be-drop {
  width: 100px;
  height: 100px;
  padding: 0.25em;
  float: left;
  margin: 10px;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="ui-widget">
  <div class="will-be-drag ui-widget-content">A</div>
  <div class="will-be-drag ui-widget-content">B</div>
  <div class="will-be-drag ui-widget-content">C</div>
</div>
<div class="ui-widget">
</div></code>```

You can also initialize some as droppable with :visible or some other condition to reduce memory overhead. Just remember to also destroy them otherwise you will just pile on the memory issue as the user moves through the page while dragging.

Body:
I want to add droppable event listener while dragging one object and hovering droppable object.

Here is my code:

$('.will-be-drag').draggable({
    helper: 'clone',
    drag: function (event, ui) {
        $('.will-be-drop').hover(function () {
            $(this).droppable({
                drop: function (event, ui) {
                    let item = ui.draggable;
                    console.log(item[0])
                    item.detach().appendTo($(this));
                }
            });
        }, function () {
            $(this).droppable('disable');
        });

    }
});

And my HTML is like that:

<?php
for($i = 0; $i <= 3000; $i++){
?>

<?php
}
?>

I'm doing that because of performance issues. I have 3k droppable object and it's freezing while dragging. It must add droppable eventlistener with only dragging $('.will-be-drag') object and hovering $('.will-be-drop').

With this code It only adds while hover not while dragging.

How can I do it?

I want javascript to breathe, it's being late when setting 3k droppable objects. There are only 30-40 draggable element. It's a table.

Body:
Here is a Hover example:

$(function() {
  $("#draggable").draggable();
  $("#droppable").droppable({
    drop: function(event, ui) {
      $(this)
        .find("p")
        .html("Dropped!");
    }
  }).hover(function(e) {
    // IN
    $(this)
      .addClass("ui-state-highlight");
  }, function(e) {
    // OUT
    $(this)
      .removeClass("ui-state-highlight");
  });
});

#draggable {
  width: 100px;
  height: 100px;
  padding: 0.5em;
  float: left;
  margin: 10px 10px 10px 0;
}

#droppable {
  width: 150px;
  height: 150px;
  padding: 0.5em;
  float: left;
  margin: 10px;
}

<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="draggable" class="ui-widget-content">
  <p>Drag me to my target</p>
</div>

<div id="droppable" class="ui-widget-header">
  <p>Drop here</p>
</div>

You can see that when you mouse over the droppable, it highlights. When you drag, it doesn't. I suspect the hover event cannot bubble up over the persistent mousedown event.

Would suggest this:

$(function() {
  function makeDrops(n) {
    var t = $(".ui-widget").eq(1);
    for (var i = 1; i <= n; i++) {
      $("<div>", {
        id: "drop-" + i,
        class: "will-be-drop ui-widget-content"
      }).appendTo(t);
    }
  }

  function inViewport(element, detectPartial) {
    element = $(element);
    detectPartial = (!!detectPartial); // if null or undefined, default to false

    var viewport = $(window),
      vpWidth = viewport.width(),
      vpHeight = viewport.height(),
      vpTop = viewport.scrollTop(),
      vpBottom = vpTop + vpHeight,
      vpLeft = viewport.scrollLeft(),
      vpRight = vpLeft + vpWidth,

      elementOffset = element.offset(),
      elementTopArea = elementOffset.top + ((detectPartial) ? element.height() : 0),
      elementBottomArea = elementOffset.top + ((detectPartial) ? 0 : element.height()),
      elementLeftArea = elementOffset.left + ((detectPartial) ? element.width() : 0),
      elementRightArea = elementOffset.left + ((detectPartial) ? 0 : element.width());

    return ((elementBottomArea <= vpBottom) && (elementTopArea >= vpTop)) && ((elementRightArea <= vpRight) && (elementLeftArea >= vpLeft));
  }

  function markVisible(c) {
    c.each(function(i, el) {
      if (inViewport(el, true)) {
        $(el).addClass("visible");
      }
    });
  }

  makeDrops(3000);

  $(".will-be-drop").droppable({
    drop: function(event, ui) {
      let item = ui.draggable;
      console.log("Drag Item " + item.text().trim() + " dropped to " + $(this).attr("id"));
      item.detach().appendTo($(this));
    },
    over: function() {
      $(this).addClass("ui-state-highlight");
    },
    out: function() {
      $(this).removeClass("ui-state-highlight");
    }
  }).droppable("disable");

  $('.will-be-drag').draggable({
    helper: 'clone',
    start: function(e, ui) {
      markVisible($(".will-be-drop"));
      $(".will-be-drop.visible").droppable("enable");
    },
    drag: function(e, ui) {
      $(".will-be-drop.visible").droppable("disable").removeClass("visible");
      markVisible($(".will-be-drop"));
      $(".will-be-drop.visible").droppable("enable");
    },
    stop: function(e, ui) {
      $(".will-be-drop").droppable("disable");
      $(".will-be-drop.ui-state-highlight").removeClass("ui-state-highlight");
    }
  });
});

.will-be-drag {
  width: 50px;
  height: 50px;
  padding: 0.25em;
  float: left;
  margin: 10px 10px 10px 0;
}

.will-be-drop {
  width: 100px;
  height: 100px;
  padding: 0.25em;
  float: left;
  margin: 10px;
}

<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="ui-widget">
  <div class="will-be-drag ui-widget-content">A</div>
  <div class="will-be-drag ui-widget-content">B</div>
  <div class="will-be-drag ui-widget-content">C</div>
</div>
<div class="ui-widget">
</div>

You can also initialize some as droppable with :visible or some other condition to reduce memory overhead. Just remember to also destroy them otherwise you will just pile on the memory issue as the user moves through the page while dragging.


问:
c# winforms communication between user controls
I'm new to the whole winforms programming. In the beginning, it seemed like all the code was ending up I'm the main form class. So i searched up how you're meant to organize code in winforms apps.

One solution I am trying right now is separate parts of the interface into user controls.

The problem is I'm not sure of the best way to communicate between controls and the main form. For example. Lets say I have a shape drawing type editing app. There's the main form and a user control which draws the objects. The main form holds the objects. And the user is able to select objects to edit and the selected object needs to be highlighted. So every time the selection changes, the main form has to tell the display control which object is now selected. Imagine if I had several user controls that needed to know information about the state in the main form. Every time something changed I'd have to call functions in all the controls to let them update. So in addition to the main form having to store a reference to the selected object all the controls are storing it as well. And i have to make sure they are all updated.

Another issue I have is that, I have a user control that lets you set properties of objects such as size or color. In order for the main form to know that a property changed, I need a custom event for each changeable setting, and then raise those events whenever a text box or checkbox changes and pass the value back. This seems like a lot of extra work. If everything was on the main form it would be so much easier. But then the main form class would be a million lines.

Am I going about all this the wrong way?

答:
Rewinder is correct in that you should use events and INotifyPropertyChanged to handle all of the communication in the scenario you described.

Additionally, for the portion of the question in the second paragraph, why bother with an event for each setting?  Use a single event with your own custom parameters that lets the subscriber of the event know exactly what was changed.  You would still need to handle the various cases in the event handler, but it would certainly simplify things.

ContentLicense: CC BY-SA 3.0


问:
how to link to same folder and different folder with html href using header.php template?
if i am at the current address: "pages/tasks.php"

then click a link that has:

Post Task

my address becomes:

"/pages/pages/task-form.php"

i understand its because it is opening that link on top of my current folder depth. I know I can put all of the pages in the same folder, then delete the "./pages/". If I do that, then I cant access another page in a different folder. But what if I want to be able to change directories with pages, or stay in the same folder at the same time? I am using a header.php template for all pages.

答:
If you are using MySQL, it will look something like this: localhost/folder/pages/task-form.php
Simply use as many '../' as necessary to back out directories until you get to the destination that contains the main folder. in my example mentioned above, the file is 2 folders deep, so it requires 2 "../"
For this use:

Post Task

For your example:

Post Task

This will always take you to the main folder, then go to the destination of the file, even if youre already at it.
 The way you were doing it was simply opening the destination folder, and the file again, while still being at the folder, thus creating a duplicate of the folder.
 Important: You must use as many "../" as the deepest file you are accessing if it has a header.php linked to it. You can use 10 of "../" even if youre not 10 deep. It cant back out more than the most containing folder.

Body:
If you are using MySQL, it will look something like this: localhost/folder/pages/task-form.php
Simply use as many '../' as necessary to back out directories until you get to the destination that contains the main folder. in my example mentioned above, the file is 2 folders deep, so it requires 2 "../"
For this use:

<li><a href="../../folder/pages/task-form.php">Post Task</a></li>

For your example:

<li><a href="../pages/task-form.php">Post Task</a></li>

This will always take you to the main folder, then go to the destination of the file, even if youre already at it.
 The way you were doing it was simply opening the destination folder, and the file again, while still being at the folder, thus creating a duplicate of the folder.
 Important: You must use as many "../" as the deepest file you are accessing if it has a header.php linked to it. You can use 10 of "../" even if youre not 10 deep. It cant back out more than the most containing folder.


问:
Azure AD B2C TOTP sample
Trying to get the B2C TOTP sample working and having issues uploading the custom policy files. (github repo here: github azure b2c totp sample)

I started with the TrustFrameworkBase.xml from the SocialAndLocalAccounts policy starter pack. Added my tenant in the appropriate places and uploaded - success. Next the TrustFrameworkExtensions.xml from the github repo - created the WebApp-GraphAPI-DirectoryExtensions application as indicated in the docs - plus the IdentityExperienceFramework app and the ProxyIdentityExperienceFramework app. Placed the ID's in  the appropriate places in the extensions policy file and uploaded it - I receive the following error:

Validation failed: 2 validation error(s) found in policy "B2C_1A_TOTP_TRUSTFRAMEWORKEXTENSIONS" of tenant "______test.onmicrosoft.com".User journey "SignUpOrSignIn" in policy "B2C_1A_TOTP_TrustFrameworkExtensions" of tenant ""______test.onmicrosoft.com" has step 5 with 2 claims exchanges. It must be preceded by a claims provider selection in order to determine which claims exchange can be used.User journey "SignUpOrSignIn" in policy "B2C_1A_TOTP_TrustFrameworkExtensions" of tenant "______test.onmicrosoft.com" has step 6 with 2 claims exchanges. It must be preceded by a claims provider selection in order to determine which claims exchange can be used.

Any pointers as to what I am missing?

Added SignUpOrSignIn user journey as requested:

```<code><UserJourney Id="SignUpOrSignIn">
  <OrchestrationSteps>

    <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
      <ClaimsProviderSelections>
        <ClaimsProviderSelection TargetClaimsExchangeId="FacebookExchange" />
        <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
      </ClaimsProviderSelections>
      <ClaimsExchanges>
        <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <!-- Check if the user has selected to sign in using one of the social providers -->
    <OrchestrationStep Order="2" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
          <Value>objectId</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="FacebookExchange" TechnicalProfileReferenceId="Facebook-OAUTH" />
        <ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <!-- For social IDP authentication, attempt to find the user account in the directory. -->
    <OrchestrationStep Order="3" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
          <Value>authenticationSource</Value>
          <Value>localAccountAuthentication</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="AADUserReadUsingAlternativeSecurityId" TechnicalProfileReferenceId="AAD-UserReadUsingAlternativeSecurityId-NoError" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <!-- Show self-asserted page only if the directory does not have the user account already (i.e. we do not have an objectId).
      This can only happen when authentication happened using a social IDP. If local account was created or authentication done
      using ESTS in step 2, then an user account must exist in the directory by this time. -->
    <OrchestrationStep Order="4" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
          <Value>objectId</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="SelfAsserted-Social" TechnicalProfileReferenceId="SelfAsserted-Social" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <!-- The previous step (SelfAsserted-Social) could have been skipped if there were no attributes to collect
         from the user. So, in that case, create the user in the directory if one does not already exist
         (verified using objectId which would be set from the last step if account was created in the directory. -->
    <OrchestrationStep Order="5" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
          <Value>objectId</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="AADUserWrite" TechnicalProfileReferenceId="AAD-UserWriteUsingAlternativeSecurityId" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <!-- Demo: The following orchestration step is always executed.
     This step reads any user attributes that we may not have received when authenticating using ESTS so they
     include the AppCode MFA attributes
      in the token. -->
    <OrchestrationStep Order="6" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <!-- Demo: The following orchestration step is executed only for unregistered
    accounts (new created account or if user cancel the sign-up process).
    It generates a verification app secret key for the user (none interactive step). -->
    <OrchestrationStep Order="7" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
          <Value>extension_StrongAuthenticationAppSecretKey</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="AppFactorGenerateTotpWebHook" TechnicalProfileReferenceId="AppFactor-GenerateTotpWebHook" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <!-- Demo: The following orchestration step is executed only for unregistered
    accounts (new created account or if user cancel the sign-up process).
    It registers a verification app through QR code that mobile authentication app should scan. -->
    <OrchestrationStep Order="8" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="false">
          <Value>strongAuthenticationAppQRCodeBitmap</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="AppFactorRegisterExchange" TechnicalProfileReferenceId="AppFactor-Register" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <!-- Demo: The following orchestration step is executed only for registered accounts.
    It asks the user to provide the TOTP code and verifies the provided code (using validation technical profile). -->
    <OrchestrationStep Order="9" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
          <Value>strongAuthenticationAppQRCodeBitmap</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="AppFactorChallengeExchange" TechnicalProfileReferenceId="AppFactor-Challenge" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <!-- Demo: The following orchestration step is always executed.
    It updates the verification app time step matched for a given user in the Azure Active Directory.
    An error is raised if the user does not exist. -->
    <OrchestrationStep Order="10" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="AADWriteUserAppCodeByObjectId" TechnicalProfileReferenceId="AAD-WriteUserAppCodeByObjectId" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="11" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />

  </OrchestrationSteps>
  <ClientDefinition ReferenceId="DefaultWeb" />
</UserJourney>
</code>```

答: This happens when you have 2 user journeys with the same Id.</p>

Title: Azure AD B2C TOTP sample

Body:
Trying to get the B2C TOTP sample working and having issues uploading the custom policy files. (github repo here: github azure b2c totp sample)

I started with the TrustFrameworkBase.xml from the SocialAndLocalAccounts policy starter pack. Added my tenant in the appropriate places and uploaded - success. Next the TrustFrameworkExtensions.xml from the github repo - created the WebApp-GraphAPI-DirectoryExtensions application as indicated in the docs - plus the IdentityExperienceFramework app and the ProxyIdentityExperienceFramework app. Placed the ID's in  the appropriate places in the extensions policy file and uploaded it - I receive the following error:

Validation failed: 2 validation error(s) found in policy "B2C_1A_TOTP_TRUSTFRAMEWORKEXTENSIONS" of tenant "______test.onmicrosoft.com".User journey "SignUpOrSignIn" in policy "B2C_1A_TOTP_TrustFrameworkExtensions" of tenant ""______test.onmicrosoft.com" has step 5 with 2 claims exchanges. It must be preceded by a claims provider selection in order to determine which claims exchange can be used.User journey "SignUpOrSignIn" in policy "B2C_1A_TOTP_TrustFrameworkExtensions" of tenant "______test.onmicrosoft.com" has step 6 with 2 claims exchanges. It must be preceded by a claims provider selection in order to determine which claims exchange can be used.

Any pointers as to what I am missing?

Added SignUpOrSignIn user journey as requested:

<UserJourney Id="SignUpOrSignIn">
  <OrchestrationSteps>

    <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
      <ClaimsProviderSelections>
        <ClaimsProviderSelection TargetClaimsExchangeId="FacebookExchange" />
        <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
      </ClaimsProviderSelections>
      <ClaimsExchanges>
        <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="2" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
          <Value>objectId</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="FacebookExchange" TechnicalProfileReferenceId="Facebook-OAUTH" />
        <ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="3" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
          <Value>authenticationSource</Value>
          <Value>localAccountAuthentication</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="AADUserReadUsingAlternativeSecurityId" TechnicalProfileReferenceId="AAD-UserReadUsingAlternativeSecurityId-NoError" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="4" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
          <Value>objectId</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="SelfAsserted-Social" TechnicalProfileReferenceId="SelfAsserted-Social" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="5" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
          <Value>objectId</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="AADUserWrite" TechnicalProfileReferenceId="AAD-UserWriteUsingAlternativeSecurityId" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="6" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="7" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
          <Value>extension_StrongAuthenticationAppSecretKey</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="AppFactorGenerateTotpWebHook" TechnicalProfileReferenceId="AppFactor-GenerateTotpWebHook" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="8" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="false">
          <Value>strongAuthenticationAppQRCodeBitmap</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="AppFactorRegisterExchange" TechnicalProfileReferenceId="AppFactor-Register" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="9" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
          <Value>strongAuthenticationAppQRCodeBitmap</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="AppFactorChallengeExchange" TechnicalProfileReferenceId="AppFactor-Challenge" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="10" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="AADWriteUserAppCodeByObjectId" TechnicalProfileReferenceId="AAD-WriteUserAppCodeByObjectId" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="11" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />

  </OrchestrationSteps>
  <ClientDefinition ReferenceId="DefaultWeb" />
</UserJourney>


问:
check if email exsite in txt file using PHP
I'm using this code to check if the entered email is existe or not in text file

```<code>$handle = fopen("http://mywebsite/u.txt", "r");
if ($handle) {
    while (($line = fgets($handle)) !== false) {
        $line = preg_replace('/\s+/', ' ', $line);
        if($line=$email){
            echo "email existe";
        }
    }

    fclose($handle);
} else {
    // error opening the file.
}
</code>```

the output is the same for exsiting emails and not exsiting email in the text file

email existeemail existeemail existe

the text file contains as a test emails

test@test.com

hello@world.com

test@t.com

if i did == it didn't enter the condition when the $line = $email

trying with

```<code>echo $line." ".$email;
</code>```

OUTPUT

test@test.com test@test.comtest@test.com test@test.comtest@test.com
  test@test.com

答:
Your code failed for 2 reasons.

1) if($line=$email) is an assignment method and will always be TRUE. You were looking to use the == comparison method.

2) You need to use trim() since that will take care of new line characters that are getting included in your file. This was outlined by another member here, being Aynber. Kudos to them.

Per:

"You might need to trim() both the line and the email to make sure there's no whitespace/new lines – aynber".

and

"put var_dump($line); after your preg_replace, it still has a space after it."

Body:
I'm using this code to check if the entered email is existe or not in text file

$handle = fopen("http://mywebsite/u.txt", "r");
if ($handle) {
    while (($line = fgets($handle)) !== false) {
        $line = preg_replace('/\s+/', ' ', $line);
        if($line=$email){
            echo "email existe";
        }
    }

    fclose($handle);
} else {
    // error opening the file.
}

the output is the same for exsiting emails and not exsiting email in the text file

email existeemail existeemail existe

the text file contains as a test emails

test@test.com

hello@world.com

test@t.com

if i did == it didn't enter the condition when the $line = $email

trying with

echo $line." ".$email;

OUTPUT

test@test.com test@test.comtest@test.com test@test.comtest@test.com
  test@test.com


问:
Java - binary insertion sort StackOverFlowError
I'm trying to write binary insertion sort in java.

```<code>
    public static int binarySearch(double[] a, int max, int min, double k) {
      if (max == min)
         return (k > a[min]) ? (min + 1) : min;
      int mid = (max + min) / 2;
      if (k == a[mid])
         return mid;
      else if (k < a[mid])
         return binarySearch(a, mid - 1, min, k);
      else
         return binarySearch(a, max, mid + 1, k);
   }

   public static void binaryInsertionSort(double[] a) {
      // TODO!!!
      for(int i = 1; i < a.length; ++i) {
         int  j = i - 1;
         double tmp = a[i];
         int l = binarySearch(a, j, 0, tmp);
         while(j >= l) {
            a[j + 1] = a[j];
            --j;
         }
         a[l] = tmp;
      }
   }
</code>```

But when I test it with

```<code>      a = new double[] {1., 3., 2.};
      DoubleSorting.binaryInsertionSort (a);
</code>```

It returns java.lang.StackOverflowError. I used pretty much the same code in C++, tested it with the same input and it works fine. But I don't know why it doesn't work in Java.

答:
You should have provided a different example. The stackoverflow error occurs for a sequence like {4., 3., 2.}, while {1., 3., 2.} does not seem to have an apparent problem.

Running it with the other sequence results in the following calls of your binarySearch method:

```<code>[4.0, 3.0, 2.0], 0, 0, 3.0
[3.0, 4.0, 2.0], 1, 0, 2.0
[3.0, 4.0, 2.0], -1, 0, 2.0
</code>```

After that it just continues with repeating the last call till the stack overflows.
As far as I understand your idea, you do not want to pass -1 here, so you could just change one line:

```<code>return binarySearch(a, Math.max(0, mid - 1), min, k);
</code>```

Next time you run into such a problem I recommend you to use a debugger, possibly combined with some additional System.out's.

Body:
I'm trying to write binary insertion sort in java.

    public static int binarySearch(double[] a, int max, int min, double k) {
      if (max == min)
         return (k > a[min]) ? (min + 1) : min;
      int mid = (max + min) / 2;
      if (k == a[mid])
         return mid;
      else if (k < a[mid])
         return binarySearch(a, mid - 1, min, k);
      else
         return binarySearch(a, max, mid + 1, k);
   }

   public static void binaryInsertionSort(double[] a) {
      // TODO!!!
      for(int i = 1; i = l) {
            a[j + 1] = a[j];
            --j;
         }
         a[l] = tmp;
      }
   }

But when I test it with

      a = new double[] {1., 3., 2.};
      DoubleSorting.binaryInsertionSort (a);

It returns java.lang.StackOverflowError. I used pretty much the same code in C++, tested it with the same input and it works fine. But I don't know why it doesn't work in Java.

Body:
You should have provided a different example. The stackoverflow error occurs for a sequence like {4., 3., 2.}, while {1., 3., 2.} does not seem to have an apparent problem.

Running it with the other sequence results in the following calls of your binarySearch method:

[4.0, 3.0, 2.0], 0, 0, 3.0
[3.0, 4.0, 2.0], 1, 0, 2.0
[3.0, 4.0, 2.0], -1, 0, 2.0

After that it just continues with repeating the last call till the stack overflows.
As far as I understand your idea, you do not want to pass -1 here, so you could just change one line:

return binarySearch(a, Math.max(0, mid - 1), min, k);

Next time you run into such a problem I recommend you to use a debugger, possibly combined with some additional System.out's.


问:
How to clear screen of minicom terminal using serial UART
I want to clear minicom terminal screen from UART connected to PC /dev/ttyUSB0. I know how to do it in PC by using shortcut Ctrl + A then Z and select C or Ctrl + A then C. Now I wanted to do the same by using UART. How to do this?

答:
Now I wanted to do the same by using UART.

The UART is employed to simply transfer data.  The UART has no access nor can it clear or control a minicom terminal screen/window.

Perhaps you are asking how the remote side of the serial connection can clear the screen, e.g. by sending a command sequence?

That answer would depend on which terminal emulation (e.g. ANSI or VT102) is configured for the minicom terminal, and if that terminal definition has a erase screen command string (aka escape sequence).

Turns out that the erase screen escape sequence is the same for both ANSI and VT102 terminals.

```<code>Esc[2J  Erase Display:
        Clears the screen and moves the cursor to the home position (line 0, column 0).
</code>```

When the minicom terminal receives (from the remote side or when local echo is enabled) the 4-byte character sequence of Esc[2J, this escape sequence is intercepted, not displayed, and then the terminal window will be cleared.

The four characters are:

```<code> Esc     the ASCII Escape character, value 0x1B.
 [       the ASCII left square brace character, value 0x5B.
 2       the ASCII character for numeral 2, value 0x32.
 J       the ASCII character for the letter J, value 0x4A.
</code>```

References

ANSI Escape sequences

ANSI/VT100 Terminal Control Escape Sequences.

Body:
Now I wanted to do the same by using UART.

The UART is employed to simply transfer data.  The UART has no access nor can it clear or control a minicom terminal screen/window.

Perhaps you are asking how the remote side of the serial connection can clear the screen, e.g. by sending a command sequence?

That answer would depend on which terminal emulation (e.g. ANSI or VT102) is configured for the minicom terminal, and if that terminal definition has a erase screen command string (aka escape sequence).

Turns out that the erase screen escape sequence is the same for both ANSI and VT102 terminals.

Esc[2J  Erase Display:
        Clears the screen and moves the cursor to the home position (line 0, column 0).

When the minicom terminal receives (from the remote side or when local echo is enabled) the 4-byte character sequence of Esc[2J, this escape sequence is intercepted, not displayed, and then the terminal window will be cleared.

The four characters are:

 Esc     the ASCII Escape character, value 0x1B.
 [       the ASCII left square brace character, value 0x5B.
 2       the ASCII character for numeral 2, value 0x32.
 J       the ASCII character for the letter J, value 0x4A.

References

ANSI Escape sequences

ANSI/VT100 Terminal Control Escape Sequences.