Home > Archive > AWK > November 2004 > I would like an eval function for awk
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
I would like an eval function for awk
|
|
| Steve Calfee 2004-11-16, 6:50 pm |
| Hi, Guys,
First let me say that this is the friendliest and most helpful of the
newsgroups I ever go to. I am a big fan of awk and have used it in
various flavors for years. Yes, I even used tawk on dos. I especially
liked its compiler. (On Linux the compiler is not needed since scripts
can be executable.)
Anyway, I sometimes try to do too much in awk. I wrote a complete
macro assembler in it, but I do not like it, it is too complicated.
Someone here suggested using M4 and I have been trying it. It is a
able to do the assembler easier than awk, but forces a weird M4 syntax
on the original source (ie. MOV(src,dest) instead of the normal
assembler syntax: MOV src,dest etc). I find its quote and parenthesis
laden syntax very hard to read and debug.
In short I like AWK better, but having to do a recursive descent
parser is so cumbersome. If instead there was an eval(x) function, it
would yield a more normal AWK like program instead of being so C like.
What I would like to see for eval(x) is to have awk push its entire
internal state ($0, NF, and all builtin variables). Then I would like
to see $0 replaced by x and then the main pattern match loop executed
(NOT BEGIN and END). After that eval(x) line, the state would be
popped and execution of the original $0 continued right after the
eval(x) statement. Obviously I would like eval to be recursive to some
reasonable depth, but it would be up to me using global variables to
maintain a global application state.
I don't like cluttering a simple, clean language like awk with
features (like perl), especially features that can be done as
functions or included source files. If there is a crossplatform
alternative to eval I would like to hear about it.
Any ideas? Regards, Steve
| |
| Aharon Robbins 2004-11-16, 6:50 pm |
| In article <mg70p0512bmicino7c8ceocl1j6qk9ugrg@4ax.com>,
Steve Calfee <stevecalfee@hotmail.com> wrote:
>It seems to me that anything that takes more than a "few" lines of awk
>code is meandering into the C ballpark.
Structuring an awk program with functions can mitigate this, somewhat.
>I saw Arnold Robbins' post earlier. I am willing to work with
>documented side effects of an eval function. I guess it is up to him
>if it is too difficult to implement.
As you proposed it, it is indeed too difficult to implement. Calling
it eval is also misleading, since what you want is to reinvoke the
current program on a different $0, when usually an eval would be
to construct some awk language code in a string and then evaluate it.
Although the latter has considerable precedent in m4, the shell and
perl, it would be painful to do in gawk, and I feel like gawk already
has too many features.
Of course, as with all Free Software, You Have The Source, and are
welcome to make any changes you see fit, in order to try out your
ideas.
Sorry,
Arnold
--
Aharon (Arnold) Robbins --- Pioneer Consulting Ltd. arnold AT skeeve DOT com
P.O. Box 354 Home Phone: +972 8 979-0381 Fax: +1 206 350 8765
Nof Ayalon Cell Phone: +972 50 729-7545
D.N. Shimshon 99785 ISRAEL
| |
| Jürgen Kahrs 2004-11-16, 6:50 pm |
| Steve Calfee wrote:
> I don't like cluttering a simple, clean language like awk with
> features (like perl), especially features that can be done as
> functions or included source files. If there is a crossplatform
> alternative to eval I would like to hear about it.
On 28th of October, Arnold Robbins already
commented on this idea:
>
> Right. I don't anticpate adding eval either. It opens up many cans
> of worms, both implementation wise and in terms of how you might
> accidentally affect the state of your awk program.
>
>
> See the Aho, Kernighan and Weinberger book on Awk, if I remember
> correctly. There's one in it.
He means calc3 in this file:
http://cm.bell-labs.com/cm/cs/who/bwk/awkcode.txt
In January 2000, Kenny McCormack and Alan Linton
posted extended versions:
# calc3 - infix calculator - derived from calc3 in TAPL, chapter 6.
# by Kenny McCormack, Mon 3 Jan 2000
# modified by Alan Linton, $Date: 2000/01/06 21:37:36 $, $Revision: 1.16 $
BEGIN { eval("x=86") ; eval("y=99") }
{
printf "%20s = %15s\n", $0,eval($0)
}
# The rest is functions...
function eval(s ,e) {
_S_expr = s
gsub(/[ \t]+/,"",_S_expr)
if (length(_S_expr)==0) return 0
_f = 1
e = _expr()
if (_f <= length(_S_expr))
printf("An error occurred at %s\n", substr(_S_expr,_f))
else return e
}
function _expr( var,e) { # term | term [+-] term
if (match(substr(_S_expr,_f),/^[A-Za-z_][A-Za-z0-9_]*=/)) {
var = _advance()
sub(/=$/,"",var)
return _vars[var] = _expr()
}
e = _term()
while (substr(_S_expr,_f,1) ~ /[+-]/)
e = substr(_S_expr,_f++,1) == "+" ? e + _term() : e - _term()
return e
}
function _term( e) { # factor | factor [*/%] factor
e = _factor()
while (substr(_S_expr,_f,1) ~ /[*\/%]/) {
_f++
if (substr(_S_expr,_f-1,1) == "*") return e * _factor()
if (substr(_S_expr,_f-1,1) == "/") return e / _factor()
if (substr(_S_expr,_f-1,1) == "%") return e % _factor()
}
return e
}
function _factor( e) { # factor2 | factor2^factor
e = _factor2()
if (substr(_S_expr,_f,1) != "^") return e
_f++
return e^_factor()
}
function _factor2( e) { # [+-]?factor3 | !*factor2
e = substr(_S_expr,_f)
if (e~/^[\+\-\!]/) { #unary operators [+-!]
_f++
if (e~/^\+/) return +_factor3() # only one unary + allowed
if (e~/^\-/) return -_factor3() # only one unary - allowed
if (e~/^\!/) return !(_factor2()+0) # unary ! may repeat
}
return _factor3()
}
function _factor3( e,fun,e2) { # number | varname | (expr) | function(...)
e = substr(_S_expr,_f)
#number
if (match(e,/^([0-9]+[.]?[0-9]*|[.][0-9]+)([Ee][+-]?[0-9]+)?/)) {
return _advance()
}
#function()
if (match(e,/^([A-Za-z_][A-Za-z0-9_]+)?\(\)/)) {
fun=_advance()
if (fun~/^srand()/) return srand()
if (fun~/^rand()/) return rand()
printf("error: unknown function %s\n", fun)
return 0
}
#(expr) | function(expr) | function(expr,expr)
if (match(e,/^([A-Za-z_][A-Za-z0-9_]+)?\(/)) {
fun=_advance()
if (fun~/ ^((cos)|(exp)|(int)|(log)|(sin)|(sqrt)|(
srand))?\(/) {
e=_expr()
e=_calcfun(fun,e)
}
else if (fun~/^atan2\(/) {
e=_expr()
if (substr(_S_expr,_f,1) != ",") {
printf("error: missing , at %s\n", substr(_S_expr,_f))
return 0
}
_f++
e2=_expr()
e=atan2(e,e2)
}
else {
printf("error: unknown function %s\n", fun)
return 0
}
if (substr(_S_expr,_f++,1) != ")") {
printf("error: missing ) at %s\n", substr(_S_expr,_f))
return 0
}
return e
}
#variable name
if (match(e,/^[A-Za-z_][A-Za-z0-9_]*/)) {
return _vars[_advance()]
}
#error
printf("error in factor: expected number or ( at %s\n", substr(_S_expr,_f))
return 0
}
function _calcfun(fun,e) { #built-in functions of one variable
if (fun=="(") return e
if (fun=="cos(") return cos(e)
if (fun=="exp(") return exp(e)
if (fun=="int(") return int(e)
if (fun=="log(") return log(e)
if (fun=="sin(") return sin(e)
if (fun=="sqrt(") return sqrt(e)
if (fun=="srand(") return srand(e)
}
function _advance( tmp) {
tmp = substr(_S_expr,_f,RLENGTH)
_f += RLENGTH
return tmp
}
| |
| Kenny McCormack 2004-11-16, 6:50 pm |
| In article <2vdk5gF2j49saU1@uni-berlin.de>,
William Park <opengeometry@yahoo.ca> wrote:
>Kenny McCormack <gazelle@yin.interaccess.com> wrote:
>
>I also found OP's remark rather strange. Because if you go past the
>simplistic
> /pattern/ {print}
>and do some "programming" in Awk, it's practically spitting image of C.
I think you misunderstand. I *agree* with OP. AWK should not (*) look
like C, regardless of how complex the programming.
(*) And, when done by skilled hands, it does not.
| |
| Ed Morton 2004-11-16, 6:50 pm |
|
Kenny McCormack wrote:
> In article <2vdk5gF2j49saU1@uni-berlin.de>,
> William Park <opengeometry@yahoo.ca> wrote:
>
>
>
> I think you misunderstand. I *agree* with OP. AWK should not (*) look
> like C, regardless of how complex the programming.
>
> (*) And, when done by skilled hands, it does not.
>
Whenever I find I've written an awk script that looks like C I revisit
it to see what I've done wrong. I suspect for large jobs, though, it
can't help ending up looking a tad C-ish.
Ed.
| |
| William Park 2004-11-16, 6:50 pm |
| Steve Calfee <stevecalfee@hotmail.com> wrote:
> It seems to me that anything that takes more than a "few" lines of awk
> code is meandering into the C ballpark. Unfortunately, C is rotten at
> dealing with strings.
You mean regex stuffs, don't you? Because <string.h>, <ctype.h>, and
<stdio.h> are C's strength. In any case, have you tried it in Bash
shell?
|
|
|
|
|