jtlc/parser/parser.yy
josh 3301142147 added bool type
git-svn-id: svn://anubis/jtlc/trunk@20 f5bc74b8-7b62-4e90-9214-7121d538519f
2010-01-13 22:58:07 +00:00

311 lines
6.1 KiB
Plaintext

%{
#include <stdio.h>
#include <iostream>
#include "parser.h"
using namespace std;
#define yyerror(msg) errFunc(msg, &yylloc)
int yylex(YYSTYPE *, YYLTYPE *);
extern FILE * yyin;
void errFunc(const char * str, YYLTYPE * yyllocp);
int yywrap()
{
return 1;
}
static YYSTYPE parse_result;
%}
%pure-parser
%locations
%error-verbose
/* operators */
%token ASSIGN;
%token DASSIGN;
%token DEQUALS;
%token DIVIDE;
%token EQUALS;
%token GREATER;
%token LESS;
%token MATCH;
%token MINUS;
%token MOD;
%token PLUS;
%token STAR;
/* punctuation */
%token COLON;
%token COMMA;
%token DCOLON;
%token DOLLAR;
%token DOT;
%token FROM;
%token QUESTION;
%token SEMICOLON;
%token LCURLY;
%token RCURLY;
%token LBRACKET;
%token RBRACKET;
%token LPAREN;
%token RPAREN;
/* literals */
%token INT_LITERAL;
%token REAL_LITERAL;
%token STRING_LITERAL;
/* primitive types */
%token BOOL;
%token BYTE;
%token UBYTE;
%token CHAR;
%token WCHAR;
%token SHORT;
%token USHORT;
%token INT;
%token UINT;
%token LONG;
%token ULONG;
%token FLOAT;
%token DOUBLE;
/* keywords */
%token C;
%token FALSE;
%token IMPORT;
%token MODULE;
%token RETURN;
%token STRUCT;
%token TRUE;
/* identifiers */
%token IDENTIFIER;
%%
program: program_items {
$$ = new ProgramNode();
$$->addChildren($1);
parse_result = $$;
}
;
program_items: /* empty */
| program_item program_items {
$$ = new ItemsNode();
$$->addChild($1);
$$->addChildren($2);
}
;
program_item: function {
$$ = $1;
}
| c_statement {
$$ = $1;
}
;
import: IMPORT import_name SEMICOLON
;
import_name: IDENTIFIER import_name_more
;
import_name_more: /* empty */
| DOT import_name_more_more
;
import_name_more_more: IDENTIFIER import_name_more
| STAR
;
function: IDENTIFIER LPAREN parameter_list RPAREN COLON type LCURLY function_items RCURLY {
$$ = new FunctionNode();
$$->addChild($3);
$$->addChild($6);
$$->addChildren($8);
}
;
function_items: /* empty */
| statement function_items {
$$ = new ItemsNode();
$$->addChild($1);
$$->addChildren($2);
}
;
parameter_list: /* empty */
| variable_spec parameter_list_more {
$$ = new ItemsNode();
$$->addChild($1);
$$->addChildren($2);
}
;
parameter_list_more: /* empty */
| COMMA variable_spec parameter_list_more {
$$ = new ItemsNode();
$$->addChild($2);
$$->addChildren($3);
}
;
primitive_type: BYTE {
$$ = new PrimitiveTypeNode(BYTE);
}
| UBYTE {
$$ = new PrimitiveTypeNode(UBYTE);
}
| CHAR {
$$ = new PrimitiveTypeNode(CHAR);
}
| WCHAR {
$$ = new PrimitiveTypeNode(WCHAR);
}
| SHORT {
$$ = new PrimitiveTypeNode(SHORT);
}
| USHORT {
$$ = new PrimitiveTypeNode(USHORT);
}
| INT {
$$ = new PrimitiveTypeNode(INT);
}
| UINT {
$$ = new PrimitiveTypeNode(UINT);
}
| LONG {
$$ = new PrimitiveTypeNode(LONG);
}
| ULONG {
$$ = new PrimitiveTypeNode(ULONG);
}
;
struct_type: STRUCT LCURLY struct_items RCURLY {
$$ = new StructTypeNode();
$$->addChildren($3);
}
;
struct_items: /* empty */
| struct_item struct_items {
$$ = new ItemsNode();
$$->addChild($1);
$$->addChildren($2);
}
;
struct_item: variable_declaration {
$$ = $1;
}
;
variable_declaration: variable_spec SEMICOLON {
$$ = $1;
}
;
variable_spec: IDENTIFIER COLON type {
$$ = new VariableSpecNode();
$$->addChild($1);
$$->addChild($3);
}
;
array_type: type LBRACKET RBRACKET {
$$ = new ArrayTypeNode();
$$->addChild($1);
}
;
type: primitive_type {
$$ = $1;
}
| struct_type {
$$ = $1;
}
| array_type {
$$ = $1;
}
| IDENTIFIER {
$$ = $1;
}
;
statement: expression SEMICOLON {
$$ = $1;
}
| return_statement {
$$ = $1;
}
| c_statement {
$$ = $1;
}
;
return_statement: RETURN expression SEMICOLON {
$$ = new ReturnStatementNode();
$$->addChild($2);
}
;
expression: assign_expr {
$$ = $1;
}
;
assign_expr: lvalue ASSIGN expression {
$$ = new AssignExprNode();
$$->addChild($1);
$$->addChild($3);
}
;
lvalue: IDENTIFIER {
$$ = new LValueNode();
$$->addChild($1);
}
;
c_statement: C LPAREN STRING_LITERAL RPAREN SEMICOLON {
$$ = new CStatementNode($3->getString());
}
;
%%
YYSTYPE parse(const char * fileName)
{
yyin = fopen(fileName, "r");
if (yyin == NULL)
{
cerr << "Failed to open file '" << fileName << "'" << endl;
}
else if (yyparse())
{
cerr << "Aborting." << endl;
exit(1);
}
return parse_result;
}
void errFunc(const char * str, YYLTYPE * yyllocp)
{
fprintf(stderr, "error: %s: line %d, column %d\n",
str,
yyllocp->first_line,
yyllocp->first_column);
}