Actually this looks like lburg input to me, and is probably part of
the lcc source code; the intermediate representation (IR) looks like that
of lcc. burg/iburg is a little more primitive; see
<
https://github.com/drh/iburg/blob/master/sample4.brg>.
You need to understand the formalism and the IR to understand this
code. Likewise with lex/yacc. But once you understand that, these
tools help improve the code compared to hand-coded stuff. E.g., when
using burg/iburg/lburg, you get certain optimality guarantees that
help in maintenance: E.g., when you add a correct rule, the generated
code is not going to be more costly (wrt the specified cost) than
without that rule. Hand-coded stuff typically uses greedy algorithms,
that do not give you that guarantee.
I don't think this has much connection to recognizers.
burg/iburg/lburg don't do what recognizers do, and vice versa. The
tool among the mentioned ones that is closest to recognizers is lex,
but even there the differences are big; it does not make sense to use
lex for Forth, nor do I see that recognizers would be useful for
replacing lex in existing lex applications.
Back to *burg: Here's some code from the RAFTS Forth compiler:
/* rule #cost# reducing #assembling*/
addr: I_PLUS(reg, cons) #0# drop 2drop #
addr: reg #0# drop 2drop 0 #
reg: I_FETCH(addr) #1# load-inst #asm-fetchi
reg represents the contents of a register, cons a constant, addr an
effective address, I_PLUS and I_FETCH are the IR names for + and @.
The rule and cost determine which rule is selected, then the according
reducing code is performed, which builds up a machine-level
representation, and the assembling part finally generates the machine
code; the latter step is not performed in one step because RAFTS
performs instruction scheduling and register allocation between
reducing and assembling.
>they are BURS (Bottom Up Rewriting Systems); a
>burg "reads a burg specification and writes a matcher [in C] that does
>DP [dynamic programming] at compile time." The output is a generated
>program in C, a hard-coded matcher that uses an AST as input and spits
>out optimal code sequences. The techniques can be applied to Forth code
>generation.
>
>This one is Hanson & Proebstring's iburg. The BNF is simple, but that
>deson't make the rewriting rules very pretty.
These are regular tree rules, a tree variant of regular grammars
(Chomsky Type 3); i.e., they reduce a tree to a non-terminal, or
produce a tree from a non-terminal. The rewrite stuff discussed by
Pelegri-Llopart (who introduced the BURS acronym) allowed rules like
I_PLUS(x,y): I_PLUS(y,x)
or somesuch, but none of the *burg tools that I am aware of allowed
anything other than nonterminals on the left-hand-side of the
productions, so one cannot really call them rewriting; nevertheless,
the "R" stuck.
>I believe the horrendous
>syntax is due to the expense of tokenizing and parsing this stuff in C.
What syntax would you use? These tools use yacc for parsing;
tokenizing is hand-coded in C in iburg.
- anton
--
M. Anton Ertl
http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs:
http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard:
http://www.forth200x.org/forth200x.html
EuroForth 2017:
http://euro.theforth.net/