home *** CD-ROM | disk | FTP | other *** search
- X/*
- X * Bawk C actions parser
- X */
- X#include <stdio.h>
- X#include "bawk.h"
- X
- Xstatic char operator_strength[] = {
- X0, /* 0 */
- X0, /* CHAR */
- X0, /* BOL */
- X0, /* EOL */
- X0, /* ANY */
- X0, /* CLASS */
- X0, /* NCLASS */
- X0, /* STAR */
- X0, /* PLUS */
- X0, /* MINUS */
- X0, /* ALPHA */
- X0, /* DIGIT */
- X0, /* NALPHA */
- X0, /* PUNCT */
- X0, /* RANGE */
- X0, /* ENDPAT */
- X0, /* T_STRING */
- X0, /* T_DOLLAR */
- X0, /* T_REGEXP */
- X0, /* T_REGEXP_ARG */
- X0, /* T_CONSTANT */
- X0, /* T_VARIABLE */
- X0, /* T_FUNCTION */
- X0, /* T_SEMICOLON */
- X0, /* T_EOF */
- X0, /* T_LBRACE */
- X0, /* T_RBRACE */
- X0, /* T_LPAREN */
- X0, /* T_RPAREN */
- X0, /* T_LBRACKET */
- X0, /* T_RBRACKET */
- X0, /* T_COMMA */
- X1, /* T_ASSIGN */
- X0, /* T_STAR */
- X11, /* T_MUL */
- X11, /* T_DIV */
- X11, /* T_MOD */
- X10, /* T_ADD */
- X0, /* T_UMINUS */
- X10, /* T_SUB */
- X9, /* T_SHL */
- X9, /* T_SHR */
- X8, /* T_LT */
- X8, /* T_LE */
- X8, /* T_GT */
- X8, /* T_GE */
- X7, /* T_EQ */
- X7, /* T_NE */
- X0, /* T_NOT */
- X0, /* T_ADDROF */
- X6, /* T_AND */
- X5, /* T_XOR */
- X4, /* T_OR */
- X0, /* T_LNOT */
- X3, /* T_LAND */
- X2, /* T_LOR */
- X0, /* T_INCR */
- X0, /* T_DECR */
- X0, /* T_POSTINCR */
- X0, /* T_POSTDECR */
- X0, /* T_IF */
- X0, /* T_ELSE */
- X0, /* T_WHILE */
- X0, /* T_BREAK */
- X0, /* T_CHAR */
- X0, /* T_INT */
- X0, /* T_BEGIN */
- X0, /* T_END */
- X0, /* T_NF */
- X0, /* T_NR */
- X0, /* T_FS */
- X0, /* T_RS */
- X0, /* T_FILENAME */
- X0, /* T_STATEMENT */
- X0, /* T_DECLARE */
- X0 /* T_ARRAY_DECLARE */
- X};
- X
- XEXPR_NODE *stmt_parse()
- X{
- X /*
- X * Parse a statement.
- X */
- X register EXPR_NODE *root = NULL, *end_pointer, *tmp;
- X
- X DBUG_ENTER("stmt_parse");
- X switch ( Token )
- X {
- X case T_EOF:
- X break;
- X case T_CHAR:
- X case T_INT:
- X root = declist_parse();
- X break;
- X case T_LBRACE:
- X /*
- X * parse a compound statement
- X */
- X getoken();
- X while ( Token != T_RBRACE )
- X {
- X tmp = get_expr_node((char) T_STATEMENT);
- X if(!root) {
- X root = end_pointer = tmp;
- X } else {
- X end_pointer->right = tmp;
- X end_pointer = tmp;
- X }
- X end_pointer->left = stmt_parse();
- X }
- X if ( Token==T_RBRACE )
- X getoken();
- X break;
- X case T_IF:
- X /*
- X * parse an "if-else" statement
- X */
- X if ( getoken() != T_LPAREN )
- X syntaxerror();
- X getoken();
- X root = get_expr_node((char) T_IF);
- X root->left = end_pointer = get_expr_node((char) T_IF);
- X end_pointer->left = expr_parse();
- X if ( Token!=T_RPAREN )
- X syntaxerror();
- X getoken();
- X end_pointer->right = stmt_parse();
- X if ( Token==T_ELSE )
- X {
- X getoken();
- X root->right = stmt_parse();
- X }
- X break;
- X case T_WHILE:
- X /*
- X * parse a "while" statement
- X */
- X root = get_expr_node((char) T_WHILE);
- X if ( getoken() != T_LPAREN )
- X syntaxerror();
- X
- X getoken();
- X root->left = expr_parse();
- X if ( Token!=T_RPAREN )
- X syntaxerror();
- X
- X getoken();
- X root->right = stmt_parse();
- X break;
- X case T_BREAK:
- X /*
- X * parse a "break" statement
- X */
- X root = get_expr_node((char) T_BREAK);
- X getoken();
- X break;
- X case T_SEMICOLON:
- X break;
- X default:
- X root = expr_parse();
- X }
- X
- X if ( Token==T_SEMICOLON )
- X getoken();
- X DBUG_RETURN(root);
- X}
- X
- XEXPR_NODE *expr_parse()
- X{
- X register EXPR_NODE *root, *tmp;
- X register char strength;
- X
- X DBUG_ENTER("expr_parse");
- X strength = operator_strength[T_ASSIGN];
- X root = expr_left_to_right_parse(strength);
- X if(strength == operator_strength[Token])
- X {
- X /* assignments are grouped right to left */
- X tmp = get_expr_node(Token);
- X tmp->left = root;
- X root = tmp;
- X getoken();
- X root->right = expr_parse();
- X }
- X DBUG_RETURN(root);
- X}
- X
- XEXPR_NODE *expr_left_to_right_parse(parent_strength)
- Xregister char parent_strength;
- X{
- X register EXPR_NODE *root, *tmp;
- X register char strength;
- X
- X DBUG_ENTER("expr_left_to_right_parse");
- X root = primary_parse();
- X if(parent_strength < (strength = operator_strength[Token]))
- X {
- X while(strength == operator_strength[Token])
- X {
- X tmp = get_expr_node(Token);
- X tmp->left = root;
- X root = tmp;
- X getoken();
- X root->right = expr_left_to_right_parse(strength);
- X }
- X }
- X DBUG_RETURN(root);
- X}
- X
- XEXPR_NODE *primary_parse()
- X{
- X register EXPR_NODE *root = NULL, *end_pointer, *tmp;
- X register int lpar;
- X
- X DBUG_ENTER("primary_parse");
- X switch ( Token )
- X {
- X case T_LPAREN:
- X /*
- X * it's a parenthesized expression
- X */
- X getoken();
- X root = expr_parse();
- X if ( Token!=T_RPAREN )
- X error( "missing ')'", ACT_ERROR );
- X getoken();
- X break;
- X case T_LNOT:
- X case T_NOT:
- X case T_INCR:
- X case T_DECR:
- X case T_DOLLAR:
- X root = get_expr_node(Token);
- X getoken();
- X root->left = primary_parse();
- X break;
- X case T_SUB:
- X root = get_expr_node((char) T_UMINUS);
- X getoken();
- X root->left = primary_parse();
- X break;
- X case T_MUL:
- X root = get_expr_node((char) T_STAR);
- X getoken();
- X root->left = primary_parse();
- X break;
- X case T_AND:
- X root = get_expr_node((char) T_ADDROF);
- X getoken();
- X root->left = primary_parse();
- X break;
- X case T_ADD:
- X getoken();
- X root = primary_parse();
- X break;
- X case T_CONSTANT:
- X root = get_expr_node(Token);
- X root->left = (EXPR_NODE *) getmemory(sizeof(DATUM));
- X ((DATUM *) (root->left))->ival = Value.ival;
- X getoken();
- X break;
- X case T_FUNCTION:
- X root = get_expr_node(Token);
- X root->left = (EXPR_NODE *) getmemory(sizeof(DATUM));
- X ((DATUM *) (root->left))->ival = Value.ival;
- X getoken();
- X if ( Token==T_LPAREN )
- X {
- X lpar = 1;
- X getoken();
- X }
- X else
- X lpar = 0;
- X /*
- X * Parse arguments into a list of expressions.
- X */
- X if ( Token!=T_RPAREN && Token!=T_EOF )
- X {
- X for ( ;; )
- X {
- X tmp = get_expr_node((char) T_FUNCTION);
- X if(!root->right) {
- X root->right = end_pointer = tmp;
- X } else {
- X end_pointer->right = tmp;
- X end_pointer = tmp;
- X }
- X end_pointer->left = expr_parse();
- X if((tmp = end_pointer->left) &&
- X (tmp->operator == T_REGEXP))
- X tmp->operator = T_REGEXP_ARG;
- X if ( Token==T_COMMA )
- X getoken();
- X else
- X break;
- X }
- X }
- X if ( lpar )
- X if( Token!=T_RPAREN )
- X error( "missing ')'", ACT_ERROR );
- X else
- X getoken();
- X break;
- X case T_REGEXP:
- X case T_STRING:
- X root = get_expr_node(Token);
- X root->left = (EXPR_NODE *) getmemory(strlen(Value.dptr) + 1);
- X strcpy((char *) root->left, Value.dptr);
- X getoken();
- X break;
- X case T_NF:
- X case T_NR:
- X case T_FS:
- X case T_RS:
- X case T_FILENAME:
- X case T_BEGIN:
- X case T_END:
- X root = get_expr_node(Token);
- X getoken();
- X break;
- X case T_VARIABLE:
- X root = get_expr_node(Token);
- X root->left = (EXPR_NODE *) Value.dptr;
- X getoken();
- X break;
- X case T_EOF:
- X break;
- X default:
- X syntaxerror();
- X }
- X /*
- X * a "[" means it's an array reference
- X */
- X if ( Token==T_LBRACKET )
- X {
- X tmp = get_expr_node(Token);
- X tmp->left = root;
- X root = tmp;
- X getoken();
- X root->right = expr_parse();
- X if ( Token!=T_RBRACKET )
- X error( "missing ']'", ACT_ERROR );
- X getoken();
- X }
- X
- X if ( Token==T_INCR || Token==T_DECR )
- X {
- X tmp = get_expr_node((char)
- X ((Token==T_INCR) ? T_POSTINCR : T_POSTDECR));
- X tmp->left = root;
- X root = tmp;
- X }
- X DBUG_RETURN(root);
- X}
- X
- Xvoid syntaxerror()
- X{
- X DBUG_ENTER("syntaxerror");
- X error( "syntax error", ACT_ERROR );
- X DBUG_VOID_RETURN;
- X}
-