What it looks like in BNF
<myword> ::= "hello" "world" ;
What it looks like in lua, with data-structures
production_rules = { "<myword>", "::=", "hello", "world", ";" }
production_rules = { ["<myword>"]={"hello", "world"} }
terminals = { "hello ", "world" }
non_terminals = { "<myword>" }
ASIDE:
This would actually be a bit easier if BNF was defined with postfix: (since forth is a post fix language)
"world" "hello" ; <myword> ::=
with:
-- add words to definition
BNF[";"] = function (stack)
local non_terminal = pop(BNF)
BNF[non_terminal] = {}
repeat push(BNF[non_terminal], pop(stack)) until #stack == 0 ; end
In this case the termination symbol ;
, wouldnโt be as neccesary.
Since ::=
would pop the string at the top of the stack (myword
),
we could choose to either have what remains on the stack as being the definition (of myword
),
or specify the amount of words that are whithin the defintion, for example:
"world" "hello" 2 <myword> ::=
"everything" "is" "how" "world" "hello" 5 <anotherword> ::=
The reason stack-based languages donโt define their words like this (in postfix), is that the intrepreter would execute the words that are part of a definition, for example:
: add5andthenprint ( num -- ) 5 + . ; (1)
5 + . 3 add5andthenprint ::= (2)
5 + . ; add5andthenprint ::= (3)
-
a word defined, as its usually defined in forth, the
:
tells it to stop executing and enter compilation mode -
a word defined with our weird postfix notation
-
another word defined with our weird postfix notation, hereโs lets assume that
;
pushes the number3
onto the stack
https://www.lua.org/cgi-bin/demo