// Som grammar for LL(1) parser 11 Jan 2004
//   generate som code     27 Jan 2004

$ // parser Som-som generated from parse-s.txt 15 June 2006
$ // global: Nlv, tok, tokvalue, nenum

top -> tkTO fundef | tkCOLON macro | ex #
fundef ->
  tkIDEN $'ypush tokvalue' args $'setfname tyFUNC' tkEQ ex $'dofun tkTO' #
macro ->
  tkIDEN $'ypush tokvalue' args $'setfname tyMAC' tkEQ ex $'dofun tkCOLON' #
args ->
  @ tkIDEN $'enterLocal tokvalue' args |
  tkBAR $'ypush Nlv' local |
  $'ypush Nlv' nil #
local -> @ tkIDEN $'enterLocal tokvalue' local | nil #

ex -> tkBB $'ypush MARK' exs tkBE $'doblock' | ex1 #
exs -> @ ex1 exs | nil #
ex1 ->
  tkIF ex0 ex exelse $'doif' |
  tkWHILE ex0 ex $'dowhile' |
  tkFOR tkIDEN $'ypush tokvalue' ex0 ex0 ex $'dofor' |
  tkCASE ex0 tkBB $'ypush MARK' caselist tkBE $'docase' |
  tkENUM tkBB elist tkBE $'ypush NIL' |
  tkBREAK $'ypush newatom OPER tkBREAK' |
  exas #

exelse -> tkELSE ex $'ypush MARK' | nil #
elist -> tkNUMBER $'nenum = tokvalue' elist2 | elist2 #
elist2 -> @ tkIDEN $'doenum' elist2 | nil #
caselist ->
  @ label tkCOLON ex caselist |
  tkELSE $'donum #ff' tkCOLON ex |
  nil #

label ->
  tkNUMBER $'donum tokvalue' |
  tkIDEN $'dolabel' #

ex0 -> term terms #
terms -> @ bop term $'dobop' terms | nil #
term [ a ] ->
  tkNUMBER $'donum tokvalue' |
  tkSTRING $'dostring' |
  tkIDEN $'a = tokvalue' $'doiden a' |
  tkNOT ex0 $'douop tkNOT' |
  tkARRAY aspec |
  tkSYSCALL tuple $'dosys' |
  tkLPAREN ex0 tkRPAREN #

// bug: doiden with wrong name because of lex
// correct: 21 Dec 2004
//  tkIDEN $'a = search tokvalue' $'doiden a' |

// add string, iden in static array (update to Som v17)

//  tkBB $'a = ysp' alist tkBE $'dostatic a' |
//  tkBB $'a = DS' alist tkBE $'ypush newatom ADS a' |
//    correct 10 June 2006, som v23
aspec [ a ] ->
  tkBB $'a = array 0' alist tkBE $'ypush newatom ADS a' |
  ex0 $'douop tkARRAY' #

// alist ->
//  @ tkNUMBER $'M[newdata] = tokvalue' alist |
//  @ tkSTRING $'akeepStr' alist |
//  @ tkIDEN $'akeepIden' alist | nil #

alist -> @ aitem alist | nil #
aitem ->
  tkNUMBER $'M[newdata] = tokvalue' |
  tkSTRING $'akeepStr' |
  tkIDEN $'akeepIden' #

tuple ->
  tkBB tkNUMBER $'ypush MARK donum tokvalue' tuples tkBE #
tuples -> @ ex0 tuples | nil #

mod -> tkLBRACKET ex0 tkRBRACKET $'dovec' | nil #

bop ->
  tkPLUS $'ypush tok' | tkMINUS $'ypush tok' |
  tkSTAR $'ypush tok' | tkSLASH $'ypush tok' |
  tkAND $'ypush tok'  | tkBAR $'ypush tok'   |
  tkCARET $'ypush tok'| tkEQEQ $'ypush tok'  |
  tkNE $'ypush tok'   | tkLT $'ypush tok'    |
  tkLE $'ypush tok'   | tkGE $'ypush tok'    |
  tkGT $'ypush tok'   | tkMOD $'ypush tok'   |
  tkGTGT $'ypush tok' | tkLTLT $'ypush tok' #

END
