-/**
- @file parser.c
- @brief See header for details
- $Revision$
- $HeadURL$
- */
#include <sclpl.h>
/* Private Declarations
// Parsing Routines
static void fetch(Parser* parser);
static Tok* peek(Parser* parser);
-static bool parser_eof(Parser* parser);
-static void parser_resume(Parser* parser);
static void error(Parser* parser, const char* text);
static bool match(Parser* parser, TokType type);
-static Tok* accept(Parser* parser, TokType type);
-static Tok* expect(Parser* parser, TokType type);
+static bool accept(Parser* parser, TokType type);
+static void expect(Parser* parser, TokType type);
+static Tok* expect_val(Parser* parser, TokType type);
/* Grammar Definition
*****************************************************************************/
static AST* const_definition(Parser* p) {
AST* expr;
- Tok* id = expect(p, T_ID);
+ Tok* id = expect_val(p, T_ID);
if (peek(p)->type == T_LPAR) {
expr = function(p);
} else {
} else if (accept(p, T_FN)) {
expr = function(p);
} else if (match(p, T_ID)) {
- expr = Ident(expect(p,T_ID));
+ expr = Ident(expect_val(p, T_ID));
} else {
expr = literal(p);
}
static AST* definition(Parser* p) {
AST* expr;
- Tok* id = expect(p, T_ID);
+ Tok* id = expect_val(p, T_ID);
if (peek(p)->type == T_LPAR) {
expr = function(p);
} else {
} else if (accept(p, T_FN)) {
expr = function(p);
} else if (match(p, T_ID)) {
- expr = Ident(expect(p,T_ID));
+ expr = Ident(expect_val(p,T_ID));
} else {
expr = literal(p);
}
AST* func = Func();
expect(p, T_LPAR);
while(peek(p)->type != T_RPAR) {
- func_add_arg(func, Ident(expect(p,T_ID)));
+ func_add_arg(func, Ident(expect_val(p,T_ID)));
type_annotation(p);
if(peek(p)->type != T_RPAR)
expect(p, T_COMMA);
case T_STRING:
case T_INT:
case T_FLOAT:
- ret = token_to_tree(expect(p, tok->type));
+ ret = token_to_tree(expect_val(p, tok->type));
break;
default:
error(p, "Expected a literal");
return block;
}
-static AST* token_to_tree(Tok* tok)
-{
+static AST* token_to_tree(Tok* tok) {
switch (tok->type) {
case T_BOOL: return Bool(tok);
case T_CHAR: return Char(tok);
/* Parsing Routines
*****************************************************************************/
-Parser* parser_new(char* prompt, FILE* input)
-{
+Parser* parser_new(char* prompt, FILE* input) {
Parser* parser = emalloc(sizeof(Parser));
memset(parser, 0, sizeof(Parser));
parser->input = input;
return parser;
}
-static void fetch(Parser* parser)
-{
- gettoken(parser, &(parser->tok));
-}
-
-static Tok* peek(Parser* p)
-{
+static Tok* peek(Parser* p) {
if (T_NONE == p->tok.type)
gettoken(p, &(p->tok));
return &(p->tok);
}
-static bool parser_eof(Parser* parser)
-{
- return (peek(parser)->type == T_END_FILE);
-}
-
-static void parser_resume(Parser* parser)
-{
- if ((T_NONE != parser->tok.type) && (T_END_FILE != parser->tok.type))
- parser->tok.type = T_NONE;
- /* We ignore the rest of the current line and attempt to start parsing
- * again on the next line */
- fetchline(parser);
-}
-
-static void error(Parser* parser, const char* text)
-{
+static void error(Parser* parser, const char* text) {
Tok* tok = peek(parser);
fprintf(stderr, "<file>:%zu:%zu:Error: %s\n", tok->line, tok->col, text);
exit(1);
}
-static bool match(Parser* parser, TokType type)
-{
+static bool match(Parser* parser, TokType type) {
return (peek(parser)->type == type);
}
-static Tok* accept(Parser* parser, TokType type)
-{
- Tok* tok = peek(parser);
- if (tok->type == type)
+static bool accept(Parser* parser, TokType type) {
+ if (peek(parser)->type == type) {
parser->tok.type = T_NONE;
- return tok;
+ return true;
+ }
+ return false;
+}
+
+static void expect(Parser* parser, TokType type) {
+ if (!accept(parser, type))
+ error(parser, "Unexpected token");
}
-static Tok* expect(Parser* parser, TokType type)
-{
- Tok* tok = accept(parser, type);
- if (tok == NULL)
+static Tok* expect_val(Parser* parser, TokType type) {
+ Tok* tok = NULL;
+ if (peek(parser)->type == type) {
+ tok = calloc(1, sizeof(Tok));
+ *tok = *(peek(parser));
+ parser->tok.type = T_NONE;
+ } else {
error(parser, "Unexpected token");
+ }
return tok;
}