blob: 9cf6320d7a52be45b47cab5412b75b137ab2f397 [file] [log] [blame]
%{
#include "ast.h"
#include "hidl_language_y.h"
#include "parser.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *);
#define lex_scanner ps->Scanner()
%}
%parse-param { Parser* ps }
%lex-param { void *lex_scanner }
%pure-parser
%skeleton "glr.cc"
%union {
Element *element;
std::vector<Element *> *elements;
Field *field;
Fields *fields;
Type *type;
AnnotationEntry *annotation_entry;
AnnotationEntries *annotation_entries;
AnnotationValues *annotation_values;
Annotation *annotation;
AnnotationValue *annotation_value;
Annotations *annotations;
int integer;
bool boolean;
std::string *str;
std::vector<std::string *> *strings;
}
%token '(' ')' ',' '@' '=' '[' ']' '.' '{' '}' ';'
%left OR
%left AND
%left '|'
%left '^'
%left '&'
%left EQ NE
%left '<' LE '>' GE
%left RSHIFT LSHIFT
%left '+' '-'
%left '*' '/' '%'
%right '~' '!' UMINUS UPLUS
%token CONST STRUCT UNION ENUM TYPEDEF VERSION INTERFACE
%token PACKAGE GENERATES IMPORT REF VEC ON SELECTS
%token INT8 INT16 INT32 INT64 UINT8 UINT16 UINT32 UINT64
%token CHAR OPAQUE HANDLE STRINGTOK ONEWAY
%token<str> C_CHAR;
%token<element> IDENTIFIER
%token<element> COMMENT
%token<element> INTVALUE C_STR
%type<strings> namespace
%type<annotations> annotations
%type<element> dotted_ids
%type<str> imports
%type<annotation_entry> annotation_entry
%type<annotation> annotation
%type<annotation_entries> annotation_entries
%type<str> typedef_decl
%type<annotation_value> annotation_value
%type<annotation_values> annotation_values
%type<boolean> oneway
%type<element> scalar_value scalar_expr const_expr
%type<elements> id_list namespace_list
%type<field> disc_union_field enum_field var_decl
%type<fields> enum_fields disc_union_fields var_decls_semi func_args
%type<type> union_type disc_union_type struct_type any_type one_word_type scalar_type
%type<token> error
%%
document
: comments intro '{' decls '}' ';' comments {}
comments
:
| comments COMMENT { ps->AddComment($2); }
intro
: version namespace imports annotations INTERFACE IDENTIFIER
{ ps->SetInterface($4, $6); }
version
: VERSION INTVALUE '.' INTVALUE ';'
{ ps->SetVersion($2->GetIntegerValue(), $4->GetIntegerValue()); }
namespace
: PACKAGE namespace_list ';'
{ ps->SetNamespace($2); }
imports
: {}
| imports import {}
import
: IMPORT namespace_list ';'
{ ps->AddImport($2); }
namespace_list
: IDENTIFIER
{ $$ = new std::vector<Element *>; $$->push_back($1); }
| namespace_list '.' IDENTIFIER
{ $1->push_back($3); }
decls
: comments
| decls decl comments
decl
: struct_decl {}
| enum_decl {}
| const_decl {}
| function_decl {}
| union_decl {}
| typedef_decl {}
struct_decl
: STRUCT IDENTIFIER '{' var_decls_semi '}' ';'
{ ps->AddStruct(new StructDecl($2, new StructType($4))); }
const_decl
: CONST IDENTIFIER '=' const_expr ';'
{ ps->AddConst(new Const($2, $4)); }
const_expr
: scalar_expr {}
| C_STR {}
scalar_expr
: scalar_value {}
| scalar_expr OR scalar_expr
{ $$ = new BinaryExpression($1, $3, "||", $1->Line()); }
| scalar_expr AND scalar_expr
{ $$ = new BinaryExpression($1, $3, "&&", $1->Line()); }
| scalar_expr '|' scalar_expr
{ $$ = new BinaryExpression($1, $3, "|", $1->Line()); }
| scalar_expr '^' scalar_expr
{ $$ = new BinaryExpression($1, $3, "^", $1->Line()); }
| scalar_expr '&' scalar_expr
{ $$ = new BinaryExpression($1, $3, "&", $1->Line()); }
| scalar_expr EQ scalar_expr
{ $$ = new BinaryExpression($1, $3, "==", $1->Line()); }
| scalar_expr NE scalar_expr
{ $$ = new BinaryExpression($1, $3, "!=", $1->Line()); }
| scalar_expr '<' scalar_expr
{ $$ = new BinaryExpression($1, $3, "<", $1->Line()); }
| scalar_expr LE scalar_expr
{ $$ = new BinaryExpression($1, $3, "<=", $1->Line()); }
| scalar_expr '>' scalar_expr
{ $$ = new BinaryExpression($1, $3, ">", $1->Line()); }
| scalar_expr GE scalar_expr
{ $$ = new BinaryExpression($1, $3, ">=", $1->Line()); }
| scalar_expr RSHIFT scalar_expr
{ $$ = new BinaryExpression($1, $3, ">>", $1->Line()); }
| scalar_expr LSHIFT scalar_expr
{ $$ = new BinaryExpression($1, $3, "<<", $1->Line()); }
| scalar_expr '+' scalar_expr
{ $$ = new BinaryExpression($1, $3, "+", $1->Line()); }
| scalar_expr '-' scalar_expr
{ $$ = new BinaryExpression($1, $3, "-", $1->Line()); }
| scalar_expr '*' scalar_expr
{ $$ = new BinaryExpression($1, $3, "*", $1->Line()); }
| scalar_expr '/' scalar_expr
{ $$ = new BinaryExpression($1, $3, "/", $1->Line()); }
| scalar_expr '%' scalar_expr
{ $$ = new BinaryExpression($1, $3, "%", $1->Line()); }
| '(' scalar_expr ')'
{ $$ = new ParenthesizedExpression($2, "()", $2->Line()); }
| '~' scalar_expr
{ $$ = new UnaryExpression($2, "~", $2->Line()); }
| '!' scalar_expr
{ $$ = new UnaryExpression($2, "!", $2->Line()); }
| '+' scalar_expr %prec UMINUS
{ $$ = new UnaryExpression($2, "+", $2->Line()); }
| '-' scalar_expr %prec UPLUS
{ $$ = new UnaryExpression($2, "-", $2->Line()); }
scalar_value
: C_CHAR {}
| INTVALUE {}
| IDENTIFIER {}
enum_decl
: ENUM IDENTIFIER ':' scalar_type '{' enum_fields '}' ';'
{ ps->AddEnum(new EnumDecl($2, new EnumType($4, $6))); }
function_decl
: annotations oneway IDENTIFIER '(' func_args ')' ';'
{ ps->AddFunction(new Function($1, $2, $3, $5, new Fields)); }
| annotations oneway IDENTIFIER '(' func_args ')' GENERATES '(' func_args ')' ';'
{ ps->AddFunction(new Function($1, $2, $3, $5, $9)); }
func_args
:
{ $$ = new Fields; }
| var_decl
{ $$ = new Fields; $$->Add($1); }
| func_args ',' var_decl
{ $$->Add($3); }
var_decls_semi
: var_decl ';'
{ $$ = new Fields; $$->Add($1); }
| var_decls_semi var_decl ';'
{ $$->Add($2); }
var_decl
: any_type IDENTIFIER
{ $$ = new TypedField($1, $2); }
| any_type IDENTIFIER SELECTS '(' dotted_ids ')'
{ $$ = new TypedField($1, $2, $5); }
dotted_ids
: IDENTIFIER {}
| dotted_ids '.' IDENTIFIER
{ $1->AddDottedElement($3); }
union_decl
: UNION IDENTIFIER '{' var_decls_semi '}' ';'
{ ps->AddUnion(new UnionDecl($2, new UnionType($4))); }
| UNION IDENTIFIER ':' IDENTIFIER '{' disc_union_fields '}' ';'
{ ps->AddUnion(new UnionDecl($2, new UnionType(new NamedType($4), $6))); }
typedef_decl
: TYPEDEF any_type IDENTIFIER ';'
{ ps->AddTypedef(new TypedefDecl($3, $2)); }
disc_union_fields
: disc_union_field
{ $$ = new Fields; $$->Add($1); }
| disc_union_fields disc_union_field
{ $1->Add($2); }
disc_union_field
: any_type IDENTIFIER ON '(' id_list ')' ';'
{ $$ = new TypedField($1, $2, $5); }
id_list
: IDENTIFIER
{ $$ = new std::vector<Element *>; $$->push_back($1); }
| id_list ',' IDENTIFIER
{ $1->push_back($3); }
enum_fields
: enum_field
{ $$ = new Fields; $$->Add($1); }
| enum_fields ',' enum_field
{ $1->Add($3); }
enum_field
: IDENTIFIER
{ $$ = new EnumField($1); }
| IDENTIFIER '=' scalar_expr
{ $$ = new EnumValueField($1, $3); }
annotations
: {$$ = new Annotations();}
| annotations annotation { $$->Add($2); }
annotation
: '@' IDENTIFIER
{ $$ = new Annotation($2); }
| '@' IDENTIFIER '(' annotation_value ')'
{ $$ = new Annotation($2, new AnnotationValues{$4}); }
| '@' IDENTIFIER '(' '{' annotation_values '}' ')'
{ $$ = new Annotation($2, $5); }
| '@' IDENTIFIER '(' annotation_entries ')'
{ $$ = new Annotation($2, $4); }
annotation_entries
: annotation_entry
{ $$ = new AnnotationEntries();
$$->emplace(*$1); } // TODO: delete $1 ?
| annotation_entries ',' annotation_entry
{ $$->emplace(*$3); }
annotation_entry
: IDENTIFIER '=' annotation_value
{ $$ = new AnnotationEntry{$1->GetText(), new AnnotationValues{$3}}; } // TODO: delete $1?
| IDENTIFIER '=' '{' annotation_values '}'
{ $$ = new AnnotationEntry{$1->GetText(), $4}; }
annotation_values
: annotation_value
{ $$ = new AnnotationValues{$1}; }
| annotation_values ',' annotation_value
{ $$->push_back($3); }
annotation_value
: const_expr
{ $$ = new AnnotationValue($1); }
| annotation
{ $$ = new AnnotationValue($1); }
scalar_type
: UINT8 { }
| UINT16 { }
| UINT32 { }
| UINT64 { }
| INT8 { }
| INT16 { }
| INT32 { }
| INT64 { }
| CHAR { }
| IDENTIFIER { $$ = new NamedType($1); } // Check at runtime if this is really scalar
one_word_type
: scalar_type
| HANDLE { }
| STRINGTOK { }
| OPAQUE { }
any_type
: one_word_type {}
| any_type '[' scalar_expr ']'
{ $$=new ArrayType($1, $3); }
| struct_type {}
| union_type {}
| disc_union_type {}
| VEC '<' any_type '>'
{ $$=new VecType($3); }
| REF '<' any_type '>'
{ $$=new RefType($3); }
struct_type
: STRUCT '{' var_decls_semi '}'
{ $$=new StructType($3); }
union_type
: UNION '{' var_decls_semi '}'
{ $$=new UnionType($3); }
disc_union_type
: UNION ':' scalar_type '{' disc_union_fields '}'
{ $$=new UnionType($3, $5); }
oneway
: { $$ = false;}
| ONEWAY { $$ = true;}
%%
#include <ctype.h>
#include <stdio.h>
void yy::parser::error(const yy::parser::location_type& l,
const std::string& errstr) {
ps->Error(l.begin.line, "%s", errstr.c_str());
}