From: Rob Pike <robpike@gmail.com>
To: Steve Johnson <scj@yaccman.com>
Cc: Bakul Shah <bakul@iitbombay.org>,
The Unix Heritage Society mailing list <tuhs@minnie.tuhs.org>
Subject: Re: [TUHS] [tuhs] Dennis Ritchie's couch
Date: Fri, 2 Jul 2021 14:40:09 +1000 [thread overview]
Message-ID: <CAKzdPgw4PMS1uMLT1gJuz=yPDJ4tfo_9MWkKRiixh57JGtVobQ@mail.gmail.com> (raw)
In-Reply-To: <CAKzdPgxGOZLLQzzPKe3kyAq1soAYPHwyeVP2iePiE8zMSk=f7g@mail.gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 1064 bytes --]
<resending with the program as an attachment, as 100K is considered big
here, and no images hidden in reply. moderator, you can kill the prior
messages. computers are hard.>
To show you what I mean, here is a parser I wrote recently for a simple Go
expression evaluator, in Go. It has all Go's precedence levels and
operators. The one odd detail is that >= etc. can be combined, as in 1 >= 2
> 3, but that doesn't matter in the context of this program and is easily
avoided with a few more lines in cmpList.
I'm using a screen grab because GMail refuses to leave my indentation
alone. I left factor off. It's got all the usual details but it's the leaf
of the grammar and of no interest here.
Note that this could easily have been made a table instead of a bunch of
one-line functions.
Parsers are easy to write. It took us a generation (or more) to understand
that, but it's remarkable nonetheless. The first big step might have been
realizing that recursion was a good idea, even if you weren't writing LISP,
if the data structure is itself recursive.
-rob
[-- Attachment #1.2: Type: text/html, Size: 1307 bytes --]
[-- Attachment #2: parse.txt --]
[-- Type: text/plain, Size: 1314 bytes --]
// parse implements a production in the expression parse hierarchy. Singles and
// doubles are strings holding the operators that are available at at this precedence
// level, while nextLevel implements the next higher precendence level.
func (p *parser) parse(singles, doubles string, nextLevel func(*parser) *Expr) *Expr {
e := nextLevel(p)
for {
if p.peek(true) == eof {
return e
}
op := p.op(singles, doubles)
if op == "" {
return e
}
e = &Expr{
op: op,
left: e,
right: nextLevel(p),
}
}
}
// orlist = andList | andList '||' orList.
func orList(p *parser) *Expr {
return p.parse("", "||", andList)
}
// andlist = cmpList | cmpList '&&' andList.
func andList(p *parser) *Expr {
return p.parse("", "&&", cmpList)
}
// cmpList = expr | expr ('>' | '<' | '==' | '!=' | '>=' | '<=') expr.
func cmpList(p *parser) *Expr {
return p.parse("+-|^!><", "==!=>=<=", expr)
}
// expr = term | term ('+' | '-' | '|' | '^') term.
func expr(p *parser) *Expr {
return p.parse("+-|^!", "", term)
}
// term = factor | factor ('*' | '/' | '%' | '>>' | '<<' | '&' | '&^') factor
func term(p *parser) *Expr {
return p.parse("*/%&", ">><<&^", factor)
}
// factor = constant | identifier | '+' factor | '-' factor | '^' factor | '!' factor | '(' orList ')'
func factor(p *parser) *Expr {
next prev parent reply other threads:[~2021-07-02 4:41 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-26 0:12 Nelson H. F. Beebe
2021-05-26 0:37 ` Rob Pike
2021-05-26 3:03 ` Larry McVoy
2021-05-26 4:02 ` Rob Pike
2021-05-26 6:20 ` Bakul Shah
2021-05-26 6:52 ` Rob Pike
2021-07-02 2:13 ` scj
2021-07-02 3:30 ` Rob Pike
2021-07-02 3:34 ` Rob Pike
2021-07-02 4:40 ` Rob Pike [this message]
2021-07-02 6:29 ` George Michaelson
2021-07-02 7:00 ` Bakul Shah
2021-07-02 17:17 ` [TUHS] " Tony Finch
2021-07-04 23:40 ` George Michaelson
2021-07-05 3:41 ` Bakul Shah
2021-05-26 5:13 ` [TUHS] [tuhs] " arnold
2021-05-26 4:10 ` Avindra G
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAKzdPgw4PMS1uMLT1gJuz=yPDJ4tfo_9MWkKRiixh57JGtVobQ@mail.gmail.com' \
--to=robpike@gmail.com \
--cc=bakul@iitbombay.org \
--cc=scj@yaccman.com \
--cc=tuhs@minnie.tuhs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).