示例#1
0
/**
 * EnumField = Name# [ "=" AssignValue ]
 */
static ast* parserEnumField (parserCtx* ctx) {
    debugEnter("EnumField");

    ast* Node = parserName(ctx, true, symEnumConstant);
    tokenLocation loc = ctx->location;

    if (tokenTryMatchPunct(ctx, punctAssign)) {
        Node = astCreateBOP(loc, Node, opAssign, parserAssignValue(ctx));
        Node->symbol = Node->l->symbol;
    }

    debugLeave();

    return Node;
}
示例#2
0
文件: parser.c 项目: dario23/tush
/**
 * BOP = Pipe
 * Pipe    = Logical  [{ "|" | "|>" Logical }]
 * Logical = Equality [{ "&&" | "||" Equality }]
 * Equality = Sum     [{ "==" | "!=" | "<" | "<=" | ">" | ">=" Sum }]
 * Sum     = Product  [{ "+" | "-" | "++" Product }]
 * Product = Exit     [{ "*" | "/" | "%" Exit }]
 * Exit = FnApp
 *
 * The grammar is ambiguous, but these operators are left associative,
 * which is to say:
 *    x op y op z == (x op y) op z
 */
static ast* parseBOP (parserCtx* ctx, int level) {
    /* (1) Operator precedence parsing!
      As all the productions above are essentially the same, with
      different operators, we can parse them with the same function.

      Read the comments in numbered order, this was (1)*/

    /* (5) Finally, once we reach the top level we escape the recursion
           into... */
    if (level == 5)
        return parseFnApp(ctx);

    /* (2) The left hand side is the production one level up*/
    ast* node = parseBOP(ctx, level+1);
    opKind op;

    /* (3) Accept operators associated with this level, and store
           which kind is found*/
    while (  level == 0
             ? (op =   try_match(ctx, "|") ? opPipe
                     : try_match(ctx, "|>") ? opWrite : opNull)
           : level == 1
             ? (op =   try_match(ctx, "&&") ? opLogicalAnd
                     : try_match(ctx, "||") ? opLogicalOr : opNull)
           : level == 2
             ? (op =   try_match(ctx, "==") ? opEqual
                     : try_match(ctx, "!=") ? opNotEqual
                     : try_match(ctx, "<") ? opLess
                     : try_match(ctx, "<=") ? opLessEqual
                     : try_match(ctx, ">") ? opGreater
                     : try_match(ctx, ">=") ? opGreaterEqual : opNull)
           : level == 3
             ? (op =   try_match(ctx, "+") ? opAdd
                     : try_match(ctx, "-") ? opSubtract
                     : try_match(ctx, "++") ? opConcat : opNull)
           : level == 4
             ? (op =   try_match(ctx, "*") ? opMultiply
                     : try_match(ctx, "/") ? opDivide
                     : try_match(ctx, "%") ? opModulo : opNull)
           : (op = opNull)) {
        /* (4) Bundle it up with an RHS, also the level up*/
        ast* rhs = parseBOP(ctx, level+1);
        node = astCreateBOP(node, rhs, op);
    }

    return node;
}
示例#3
0
/**
 * DeclExpr = DeclUnary [ "=" AssignValue ]
 *
 * This uses AssignValue instead of Value, skipping comma operators.
 * This is to avoid the case of
 *     int x = 5, y = 6;
 * which would be parsed as
 *     int x = (5, y = 6);
 */
static ast* parserDeclExpr (parserCtx* ctx, bool inDecl, symTag tag) {
    debugEnter("DeclExpr");

    ast* Node = parserDeclUnary(ctx, inDecl, tag);
    tokenLocation loc = ctx->location;

    if (tokenTryMatchPunct(ctx, punctAssign)) {
        if (!inDecl || tag != symId)
            errorIllegalOutside(ctx, "initializer", "a declaration");

        Node = astCreateBOP(loc, Node, opAssign, parserAssignValue(ctx));
        Node->symbol = Node->l->symbol;
        Node->symbol->impl = Node->r;
    }

    debugLeave();

    return Node;
}