std-c parser declarator
parent
d5d52af26e
commit
3ed6d7d245
|
@ -41,6 +41,7 @@ pub const Error = union(enum) {
|
|||
ExpectedStmt: SingleTokenError("expected statement, found '{}'"),
|
||||
ExpectedTypeName: SingleTokenError("expected type name, found '{}'"),
|
||||
ExpectedFnBody: SingleTokenError("expected function body, found '{}'"),
|
||||
ExpectedDeclarator: SingleTokenError("expected declarator, found '{}'"),
|
||||
ExpectedInitializer: SingleTokenError("expected initializer, found '{}'"),
|
||||
InvalidTypeSpecifier: InvalidTypeSpecifier,
|
||||
DuplicateQualifier: SingleTokenError("duplicate type qualifier '{}'"),
|
||||
|
@ -55,6 +56,7 @@ pub const Error = union(enum) {
|
|||
.ExpectedTypeName => |*x| return x.render(tokens, stream),
|
||||
.ExpectedDeclarator => |*x| return x.render(tokens, stream),
|
||||
.ExpectedFnBody => |*x| return x.render(tokens, stream),
|
||||
.ExpectedInitializer => |*x| return x.render(tokens, stream),
|
||||
.InvalidTypeSpecifier => |*x| return x.render(tokens, stream),
|
||||
.DuplicateQualifier => |*x| return x.render(tokens, stream),
|
||||
.DuplicateSpecifier => |*x| return x.render(tokens, stream),
|
||||
|
@ -70,6 +72,7 @@ pub const Error = union(enum) {
|
|||
.ExpectedTypeName => |x| return x.token,
|
||||
.ExpectedDeclarator => |x| return x.token,
|
||||
.ExpectedFnBody => |x| return x.token,
|
||||
.ExpectedInitializer => |x| return x.token,
|
||||
.InvalidTypeSpecifier => |x| return x.token,
|
||||
.DuplicateQualifier => |x| return x.token,
|
||||
.DuplicateSpecifier => |x| return x.token,
|
||||
|
@ -277,30 +280,48 @@ pub const Node = struct {
|
|||
};
|
||||
|
||||
pub const Declarator = struct {
|
||||
base: Node = Node{ .id = .Declarator },
|
||||
pointer: *Pointer,
|
||||
identifier: ?TokenIndex,
|
||||
kind: union(enum) {
|
||||
Simple,
|
||||
prefix: union(enum) {
|
||||
None,
|
||||
Identifer: TokenIndex,
|
||||
Complex: struct {
|
||||
lparen: TokenIndex,
|
||||
inner: *Declarator,
|
||||
inner: *Node,
|
||||
rparen: TokenIndex,
|
||||
},
|
||||
Fn: ParamList,
|
||||
Array: ArrayList,
|
||||
},
|
||||
suffix: union(enum) {
|
||||
None,
|
||||
Fn: struct {
|
||||
lparen: TokenIndex,
|
||||
params: Params,
|
||||
rparen: TokenIndex,
|
||||
},
|
||||
Array: Arrays,
|
||||
},
|
||||
|
||||
pub const ArrayList = std.SegmentedList(*Array, 2);
|
||||
pub const ParamList = std.SegmentedList(*Param, 4);
|
||||
pub const Arrays = std.SegmentedList(*Array, 2);
|
||||
pub const Params = std.SegmentedList(*Param, 4);
|
||||
};
|
||||
|
||||
pub const Array = union(enum) {
|
||||
Unspecified,
|
||||
Variable: TokenIndex,
|
||||
Known: *Expr,
|
||||
pub const Array = struct {
|
||||
rbracket: TokenIndex,
|
||||
inner: union(enum) {
|
||||
Inferred,
|
||||
Unspecified: TokenIndex,
|
||||
Variable: struct {
|
||||
asterisk: ?TokenIndex,
|
||||
static: ?TokenIndex,
|
||||
qual: TypeQual,
|
||||
expr: *Expr,
|
||||
},
|
||||
},
|
||||
rbracket: TokenIndex,
|
||||
};
|
||||
|
||||
pub const Pointer = struct {
|
||||
base: Node = Node{ .id = .Pointer },
|
||||
asterisk: TokenIndex,
|
||||
qual: TypeQual,
|
||||
pointer: ?*Pointer,
|
||||
|
@ -312,7 +333,7 @@ pub const Node = struct {
|
|||
Old: TokenIndex,
|
||||
Normal: struct {
|
||||
decl_spec: *DeclSpec,
|
||||
declarator: *Declarator,
|
||||
declarator: *Node,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -320,7 +341,7 @@ pub const Node = struct {
|
|||
pub const Fn = struct {
|
||||
base: Node = Node{ .id = .Fn },
|
||||
decl_spec: DeclSpec,
|
||||
declarator: *Declarator,
|
||||
declarator: *Node,
|
||||
old_decls: OldDeclList,
|
||||
body: ?*CompoundStmt,
|
||||
|
||||
|
@ -332,7 +353,7 @@ pub const Node = struct {
|
|||
decl_spec: DeclSpec,
|
||||
declarators: DeclaratorList,
|
||||
|
||||
pub const DeclaratorList = std.SegmentedList(*Declarator, 2);
|
||||
pub const DeclaratorList = Root.DeclList;
|
||||
};
|
||||
|
||||
pub const Var = struct {
|
||||
|
@ -344,7 +365,7 @@ pub const Node = struct {
|
|||
};
|
||||
|
||||
pub const Initialized = struct {
|
||||
declarator: *Declarator,
|
||||
declarator: *Node,
|
||||
eq: TokenIndex,
|
||||
init: Initializer,
|
||||
};
|
||||
|
|
|
@ -589,7 +589,7 @@ const Parser = struct {
|
|||
fn recordDeclarator(parser: *Parser) !*Node {}
|
||||
|
||||
/// Pointer <- ASTERISK TypeQual* Pointer?
|
||||
fn pointer(parser: *Parser) !?*Node.Pointer {
|
||||
fn pointer(parser: *Parser) Error!?*Node {
|
||||
const asterisk = parser.eatToken(.Asterisk) orelse return null;
|
||||
const node = try parser.arena.create(Node.Pointer);
|
||||
node.* = .{
|
||||
|
@ -599,34 +599,129 @@ const Parser = struct {
|
|||
};
|
||||
while (try parser.typeQual(&node.qual)) {}
|
||||
node.pointer = try parser.pointer();
|
||||
return &node.base;
|
||||
}
|
||||
|
||||
const Named = enum {
|
||||
Must,
|
||||
Allowed,
|
||||
Forbidden,
|
||||
};
|
||||
|
||||
/// Declarator <- Pointer? DeclaratorSuffix
|
||||
/// DeclaratorPrefix
|
||||
/// <- IDENTIFIER // if named != .Forbidden
|
||||
/// / LPAREN Declarator RPAREN
|
||||
/// / (none) // if named != .Must
|
||||
/// DeclaratorSuffix
|
||||
/// <. DeclaratorPrefix (LBRACKET ArrayDeclarator? RBRACKET)*
|
||||
/// / DeclaratorPrefix LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN
|
||||
fn declarator(parser: *Parser, named: Named) Error!?*Node {
|
||||
const ptr = try parser.pointer();
|
||||
var node: *Node.Declarator = undefined;
|
||||
// prefix
|
||||
if (parser.eatToken(.LParen)) |lparen| {
|
||||
const inner = (try parser.declarator(named)) orelse return parser.err(.{
|
||||
.ExpectedDeclarator = .{ .token = lparen + 1 },
|
||||
});
|
||||
node = try parser.arena.create(Node.Declarator);
|
||||
node.* = .{
|
||||
.pointer = ptr,
|
||||
.prefix = .{
|
||||
.Comples = .{
|
||||
.lparen = lparen,
|
||||
.inner = inner,
|
||||
.rparen = try parser.expectToken(.RParen),
|
||||
},
|
||||
},
|
||||
.suffix = .None,
|
||||
};
|
||||
} else if (named != .Forbidden) {
|
||||
if (parser.eatToken(.Identifier)) |tok| {
|
||||
node = try parser.arena.create(Node.Declarator);
|
||||
node.* = .{
|
||||
.pointer = ptr,
|
||||
.prefix = .{ .Simple = tok },
|
||||
.suffix = .None,
|
||||
};
|
||||
} else if (named == .Must) {
|
||||
return parser.err(.{
|
||||
.ExpectedToken = .{ .token = parser.it.index, .expected_id = .Identifier },
|
||||
});
|
||||
} else {
|
||||
return ptr;
|
||||
}
|
||||
} else {
|
||||
node = try parser.arena.create(Node.Declarator);
|
||||
node.* = .{
|
||||
.pointer = ptr,
|
||||
.prefix = .None,
|
||||
.suffix = .None,
|
||||
};
|
||||
}
|
||||
// suffix
|
||||
if (parser.eatToken(.LParen)) |lparen| {
|
||||
node.suffix = .{
|
||||
.Fn = .{
|
||||
.lparen = lparen,
|
||||
.params = .Node.Declarator.Params.init(parser.arena),
|
||||
.rparen = undefined,
|
||||
},
|
||||
};
|
||||
try parser.ParamDecl(node);
|
||||
node.suffix.Fn.rparen = try parser.expectToken(.RParen);
|
||||
} else {
|
||||
while (parser.arrayDeclarator()) |arr| {
|
||||
if (node.suffix == .None)
|
||||
node.suffix = .{ .Array = .Node.Declarator.Arrays.init(parser.arena) };
|
||||
try node.suffix.Array.push(arr);
|
||||
}
|
||||
}
|
||||
if (parser.eatToken(.LParen) orelse parser.eatToken(.LBracket)) |tok|
|
||||
return parser.err(.{
|
||||
.InvalidDeclarator = .{ .token = tok },
|
||||
});
|
||||
return node;
|
||||
}
|
||||
/// DirectDeclarator
|
||||
/// <- IDENTIFIER
|
||||
/// / LPAREN Declarator RPAREN
|
||||
/// / DirectDeclarator LBRACKET (ASTERISK / BracketDeclarator)? RBRACKET
|
||||
/// / DirectDeclarator LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN
|
||||
fn directDeclarator(parser: *Parser) !*Node {}
|
||||
|
||||
/// BracketDeclarator
|
||||
/// <- Keyword_static TypeQual* AssignmentExpr
|
||||
/// ArrayDeclarator
|
||||
/// <- ASTERISK
|
||||
/// / Keyword_static TypeQual* AssignmentExpr
|
||||
/// / TypeQual+ (ASTERISK / Keyword_static AssignmentExpr)
|
||||
/// / TypeQual+ AssignmentExpr?
|
||||
/// / AssignmentExpr
|
||||
fn bracketDeclarator(parser: *Parser) !*Node {}
|
||||
fn arrayDeclarator(parser: *Parser, dr: *Node.Declarator) !?*Node.Array {
|
||||
const lbracket = parser.eatToken(.LBracket) orelse return null;
|
||||
const arr = try parser.arena.create(Node.Array);
|
||||
arr.* = .{
|
||||
.lbracket = lbarcket,
|
||||
.inner = .Inferred,
|
||||
.rbracket = undefined,
|
||||
};
|
||||
if (parser.eatToken(.Asterisk)) |tok| {
|
||||
arr.inner = .{ .Unspecified = tok };
|
||||
} else {
|
||||
// TODO
|
||||
}
|
||||
arr.rbracket = try parser.expectToken(.RBracket);
|
||||
return arr;
|
||||
}
|
||||
|
||||
/// Params <- ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?
|
||||
/// ParamDecl <- DeclSpec (Declarator / AbstractDeclarator)
|
||||
fn paramDecl(parser: *Parser) !*Node {}
|
||||
|
||||
/// AbstractDeclarator <- Pointer? DirectAbstractDeclarator?
|
||||
fn abstractDeclarator(parser: *Parser) !*Node {}
|
||||
|
||||
/// DirectAbstractDeclarator
|
||||
/// <- IDENTIFIER
|
||||
/// / LPAREN DirectAbstractDeclarator RPAREN
|
||||
/// / DirectAbstractDeclarator? LBRACKET (ASTERISK / BracketDeclarator)? RBRACKET
|
||||
/// / DirectAbstractDeclarator? LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN
|
||||
fn directAbstractDeclarator(parser: *Parser) !*Node {}
|
||||
fn paramDecl(parser: *Parser, dr: *Node.Declarator) !void {
|
||||
var old_style = false;
|
||||
while (true) {
|
||||
var ds = Node.DeclSpec;
|
||||
if (try parser.declSpec(&ds)) {
|
||||
//TODO
|
||||
} else if (parser.eatToken(.Identifier)) {
|
||||
old_style = true;
|
||||
} else if (parser.eatToken(.Ellipsis)) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Expr <- AssignmentExpr (COMMA Expr)*
|
||||
fn expr(parser: *Parser) !*Node {}
|
||||
|
|
Loading…
Reference in New Issue