txr-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Txr-users] Experimental: horizontal functions.


From: Kaz Kylheku
Subject: Re: [Txr-users] Experimental: horizontal functions.
Date: Wed, 09 Nov 2011 09:04:22 -0800
User-agent: Roundcube Webmail/0.4

On Tue, 08 Nov 2011 22:07:50 -0800, I wrote:
> Hi all,
> 
> New feature in repository: horizontal matching functions.

Check this out. The following txr query parses a simple arithmetic
expression and tells you whether it is correct, or else where then
non-matching part (syntax error) begins:

@(next :args)
@(define os)@/ */@(end)@# os -> optional space
@(define mulop)@(os)@/[*\/]/@(os)@(end)
@(define addop)@(os)@/[+\-]/@(os)@(end)
@(define number)@(os)@/[0-9]+/@(os)@(end)
@(define ident)@(os)@/[A-Za-z]+/@(os)@(end)
@(define factor)@(some)(@(expr))@(or)@(number)@(or)@(ident)@(end)@(end)
@(define
term)@(some)@(factor)@(or)@(factor)@(mulop)@(term)@(or)@(addop)@(factor)@(end)@(end)
@(define expr)@(some)@(term)@(or)@(term)@(addop)@(expr)@(end)@(end)
@(cases)
@  (expr)
@  (output)
parses!
@  (end)
@(or)
@  (expr)@bad
@  (output)
error starting at "@bad"
@  (end)
@(end)

Supports add, subtract, multiply, divide, unary plus and minus and
brackets.
This was *very* easy to write. Of course, left recursion had to be
avoided,
so I refactored the grammar.

Example runs:

$ ./txr  expr.txr "3"
parses!
$ ./txr  expr.txr "a"
parses!
$ ./txr  expr.txr "a + a * (3 * 4)"
parses!
$ ./txr  expr.txr "a + a * (3 * 4) ("
error starting at " ("
$ ./txr  expr.txr "a + a * (3 * - 4)"
parses!
$ ./txr  expr.txr "a + a * (3 * - (3 + 3))"
parses!
$ ./txr  expr.txr "a + a * (3 * / (3 + 3))"
error starting at "* (3 * / (3 + 3))"
$ ./txr  expr.txr "a + a * (3 / (3 + 3))"
parses!


As you can see, this finds the longest prefix of the input which is
syntactically correct. Kind of like a regular expression, but with
memory due to recursion.

By the way, there are other ways to write this. Instead of parsing
multiple cases with @(cases), which does some wasteful redundant
processing, it should work like this:

@(define expr)@(term)@(maybe)@(addop)@(expr)@(end)@(end)

I.e. an expression is a term, which is "maybe" followed by
an additive operator and another expression. Our familiar
maybe directive covers this perfectly.

Cheers ...





reply via email to

[Prev in Thread] Current Thread [Next in Thread]