tokstyle-0.0.1: src/Tokstyle/Cimple/Parser.y
{
module Tokstyle.Cimple.Parser where
import Tokstyle.Cimple.Lexer (Alex, Lexeme (..), LexemeClass (..),
alexMonadScan)
}
-- Conflict between (static) FunctionDecl and (static) ConstDecl.
%expect 2
%name parseCimple
%error {parseError}
%lexer {lexwrap} {L undefined Eof ""}
%monad {Alex}
%tokentype {Lexeme}
%token
ID_CONST { L _ IdConst _ }
ID_FUNC_TYPE { L _ IdFuncType _ }
ID_STD_TYPE { L _ IdStdType _ }
ID_SUE_TYPE { L _ IdSueType _ }
ID_VAR { L _ IdVar _ }
break { L _ KwBreak _ }
case { L _ KwCase _ }
const { L _ KwConst _ }
continue { L _ KwContinue _ }
default { L _ KwDefault _ }
do { L _ KwDo _ }
else { L _ KwElse _ }
enum { L _ KwEnum _ }
extern { L _ KwExtern _ }
for { L _ KwFor _ }
goto { L _ KwGoto _ }
if { L _ KwIf _ }
return { L _ KwReturn _ }
sizeof { L _ KwSizeof _ }
static { L _ KwStatic _ }
struct { L _ KwStruct _ }
switch { L _ KwSwitch _ }
typedef { L _ KwTypedef _ }
union { L _ KwUnion _ }
VLA { L _ KwVla _ }
void { L _ KwVoid _ }
while { L _ KwWhile _ }
LIT_CHAR { L _ LitChar _ }
LIT_INTEGER { L _ LitInteger _ }
LIT_STRING { L _ LitString _ }
LIT_SYS_INCLUDE { L _ LitSysInclude _ }
'&' { L _ PctAmpersand _ }
'&&' { L _ PctAmpersandAmpersand _ }
'&=' { L _ PctAmpersandEq _ }
'->' { L _ PctArrow _ }
'*' { L _ PctAsterisk _ }
'*=' { L _ PctAsteriskEq _ }
'^' { L _ PctCaret _ }
'^=' { L _ PctCaretEq _ }
':' { L _ PctColon _ }
',' { L _ PctComma _ }
'!' { L _ PctEMark _ }
'!=' { L _ PctEMarkEq _ }
'=' { L _ PctEq _ }
'==' { L _ PctEqEq _ }
'>' { L _ PctGreater _ }
'>=' { L _ PctGreaterEq _ }
'>>' { L _ PctGreaterGreater _ }
'>>=' { L _ PctGreaterGreaterEq _ }
'{' { L _ PctLBrace _ }
'[' { L _ PctLBrack _ }
'<' { L _ PctLess _ }
'<=' { L _ PctLessEq _ }
'<<' { L _ PctLessLess _ }
'<<=' { L _ PctLessLessEq _ }
'(' { L _ PctLParen _ }
'-' { L _ PctMinus _ }
'-=' { L _ PctMinusEq _ }
'--' { L _ PctMinusMinus _ }
'%' { L _ PctPercent _ }
'%=' { L _ PctPercentEq _ }
'.' { L _ PctPeriod _ }
'...' { L _ PctEllipsis _ }
'|' { L _ PctPipe _ }
'|=' { L _ PctPipeEq _ }
'||' { L _ PctPipePipe _ }
'+' { L _ PctPlus _ }
'+=' { L _ PctPlusEq _ }
'++' { L _ PctPlusPlus _ }
'?' { L _ PctQMark _ }
'}' { L _ PctRBrace _ }
']' { L _ PctRBrack _ }
')' { L _ PctRParen _ }
';' { L _ PctSemicolon _ }
'/' { L _ PctSlash _ }
'/=' { L _ PctSlashEq _ }
'~' { L _ PctTilde _ }
'defined' { L _ PpDefined _ }
'#define' { L _ PpDefine _ }
'#elif' { L _ PpElif _ }
'#else' { L _ PpElse _ }
'#endif' { L _ PpEndif _ }
'#error' { L _ PpError _ }
'#if' { L _ PpIf _ }
'#ifdef' { L _ PpIfdef _ }
'#ifndef' { L _ PpIfndef _ }
'#include' { L _ PpInclude _ }
'#undef' { L _ PpUndef _ }
'\n' { L _ PpNewline _ }
%left ','
%right '=' '+=' '-=' '*=' '/=' '%=' '<<=' '>>=' '&=' '^=' '|='
%right '?' ':'
%left '||'
%left '&&'
%left '|'
%left '^'
%left '&'
%left '!=' '=='
%left '<' '<=' '>' '>='
%left '<<' '>>'
%left '+' '-'
%left '*' '/' '%'
%right CAST ADDRESS NEG DEREF sizeof '!' '~' '++' '--'
%left '->' '.' '(' '['
%%
TranslationUnit :: { [()] }
TranslationUnit
: ToplevelDecls { $1 }
ToplevelDecls :: { [()] }
ToplevelDecls
: ToplevelDecl { [$1] }
| ToplevelDecls ToplevelDecl { $2 : $1 }
ToplevelDecl :: { () }
ToplevelDecl
: PreprocIfdef(ToplevelDecls) { $1 }
| PreprocIf(ToplevelDecls) { $1 }
| PreprocInclude { $1 }
| PreprocDefine { $1 }
| PreprocUndef { $1 }
| PreprocError { $1 }
| ExternC { $1 }
| TypedefDecl { $1 }
| AggregateDecl { $1 }
| EnumDecl { $1 }
| FunctionDecl { $1 }
| ConstDecl { $1 }
PreprocIfdef(decls)
: '#ifdef' ID_CONST decls PreprocElse(decls) '#endif' { () }
| '#ifndef' ID_CONST decls PreprocElse(decls) '#endif' { () }
PreprocIf(decls)
: '#if' ConstExpr '\n' decls PreprocElse(decls) '#endif' { () }
PreprocElse(decls)
: { () }
| '#else' decls { () }
| '#elif' ConstExpr '\n' decls PreprocElse(decls) { () }
PreprocError :: { () }
PreprocError
: '#error' LIT_STRING { () }
PreprocInclude :: { () }
PreprocInclude
: '#include' LIT_STRING { () }
| '#include' LIT_SYS_INCLUDE { () }
PreprocDefine :: { () }
PreprocDefine
: '#define' ID_CONST ConstExpr '\n' { () }
| '#define' ID_CONST '\n' { () }
| '#define' ID_CONST MacroParamList MacroBody '\n' { () }
PreprocUndef :: { () }
PreprocUndef
: '#undef' ID_CONST { () }
ConstExpr :: { () }
ConstExpr
: LiteralExpr { () }
| 'defined' '(' ID_CONST ')' { () }
| PureExpr(ConstExpr) { () }
MacroParamList :: { () }
MacroParamList
: '(' ')' { () }
| '(' MacroParams ')' { () }
| '(' MacroParams ',' '...' ')' { () }
MacroParams :: { [()] }
MacroParams
: MacroParam { [$1] }
| MacroParams ',' MacroParam { $3 : $1 }
MacroParam :: { () }
MacroParam
: ID_VAR { () }
MacroBody :: { () }
MacroBody
: do CompoundStmt while '(' LIT_INTEGER ')' { () }
| FunctionCall { () }
ExternC :: { () }
ExternC
: '#ifdef' ID_CONST
extern LIT_STRING '{'
'#endif'
ToplevelDecls
'#ifdef' ID_CONST
'}'
'#endif' { () }
Stmts :: { [()] }
Stmts
: Stmt { [$1] }
| Stmts Stmt { $2 : $1 }
Stmt :: { () }
Stmt
: PreprocIfdef(Stmts) { () }
| PreprocIf(Stmts) { () }
| PreprocDefine Stmts PreprocUndef { () }
| LabelStmt { () }
| DeclStmt { () }
| CompoundStmt { () }
| IfStmt { () }
| ForStmt { () }
| WhileStmt { () }
| DoWhileStmt { () }
| AssignExpr ';' { () }
| ExprStmt ';' { () }
| FunctionCall ';' { () }
| break ';' { () }
| goto ID_CONST ';' { () }
| continue ';' { () }
| return ';' { () }
| return Expr ';' { () }
| switch '(' Expr ')' CompoundStmt { () }
IfStmt :: { () }
IfStmt
: if '(' Expr ')' CompoundStmt { () }
| if '(' Expr ')' CompoundStmt else IfStmt { () }
| if '(' Expr ')' CompoundStmt else CompoundStmt { () }
ForStmt :: { () }
ForStmt
: for '(' ForInit Opt(Expr) ';' Opt(ForNext) ')' CompoundStmt { () }
ForInit :: { () }
ForInit
: ';' { () }
| AssignExpr ';' { () }
| SingleVarDecl { () }
ForNext :: { () }
ForNext
: ExprStmt { () }
| AssignExpr { () }
Opt(x)
: { () }
| x { () }
WhileStmt :: { () }
WhileStmt
: while '(' Expr ')' CompoundStmt { () }
DoWhileStmt :: { () }
DoWhileStmt
: do CompoundStmt while '(' Expr ')' ';' { () }
LabelStmt :: { () }
LabelStmt
: case Expr ':' Stmt { () }
| default ':' Stmt { () }
| ID_CONST ':' Stmt { () }
DeclStmt :: { () }
DeclStmt
: VarDecl { () }
| VLA '(' Type ',' ID_VAR ',' Expr ')' ';' { () }
SingleVarDecl :: { () }
SingleVarDecl
: QualType Declarator ';' { () }
VarDecl :: { () }
VarDecl
: QualType Declarators ';' { () }
Declarators :: { [()] }
Declarators
: Declarator { [$1] }
| Declarators ',' Declarator { $3 : $1 }
Declarator :: { () }
Declarator
: DeclSpec(Expr) '=' InitialiserExpr { () }
| DeclSpec(Expr) { () }
InitialiserExpr :: { () }
InitialiserExpr
: InitialiserList { () }
| Expr { () }
DeclSpec(expr)
: ID_VAR { () }
| DeclSpec(expr) '[' ']' { () }
| DeclSpec(expr) '[' expr ']' { () }
InitialiserList :: { () }
InitialiserList
: '{' Initialisers '}' { () }
| '{' Initialisers ',' '}' { () }
Initialisers :: { [()] }
Initialisers
: Initialiser { [$1] }
| Initialisers ',' Initialiser { $3 : $1 }
Initialiser :: { () }
Initialiser
: Expr { () }
| InitialiserList { () }
CompoundStmt :: { () }
CompoundStmt
: '{' Stmts '}' { () }
PureExpr(x)
: x '!=' x { () }
| x '==' x { () }
| x '||' x { () }
| x '^' x { () }
| x '|' x { () }
| x '&&' x { () }
| x '&' x { () }
| x '/' x { () }
| x '*' x { () }
| x '%' x { () }
| x '+' x { () }
| x '-' x { () }
| x '<' x { () }
| x '<=' x { () }
| x '<<' x { () }
| x '>' x { () }
| x '>=' x { () }
| x '>>' x { () }
| x '?' x ':' x { () }
| '(' x ')' { () }
| '!' x { () }
| '~' x { () }
| '-' x %prec NEG { () }
| '&' x %prec ADDRESS { () }
| '(' QualType ')' x %prec CAST { () }
| sizeof '(' x ')' { () }
| sizeof '(' Type ')' { () }
LiteralExpr :: { () }
LiteralExpr
: LIT_CHAR { () }
| LIT_INTEGER { () }
| LIT_STRING { () }
| ID_CONST { () }
Expr :: { () }
Expr
: LhsExpr { () }
| ExprStmt { () }
| LiteralExpr { () }
| FunctionCall { () }
| PureExpr(Expr) { () }
AssignExpr :: { () }
AssignExpr
: LhsExpr AssignOperator Expr { () }
AssignOperator :: { () }
AssignOperator
: '=' { () }
| '*=' { () }
| '/=' { () }
| '+=' { () }
| '-=' { () }
| '&=' { () }
| '|=' { () }
| '^=' { () }
| '%=' { () }
| '<<=' { () }
| '>>=' { () }
ExprStmt :: { () }
ExprStmt
: '++' Expr { () }
| '--' Expr { () }
LhsExpr :: { () }
LhsExpr
: ID_VAR { () }
| '*' LhsExpr %prec DEREF { () }
-- TODO(iphydf): We don't want this, it's most likely a bug:
| '*' '(' QualType ')' LhsExpr %prec DEREF { () }
| LhsExpr '.' ID_VAR { () }
| LhsExpr '->' ID_VAR { () }
| LhsExpr '[' Expr ']' { () }
FunctionCall :: { () }
FunctionCall
: Expr ArgList { () }
ArgList :: { () }
ArgList
: '(' ')' { () }
| '(' Args ')' { () }
Args :: { [()] }
Args
: Expr { [$1] }
| Args ',' Expr { $3 : $1 }
EnumDecl :: { () }
EnumDecl
: typedef enum ID_SUE_TYPE EnumeratorList ID_SUE_TYPE ';' { () }
EnumeratorList :: { () }
EnumeratorList
: '{' Enumerators '}' { () }
| '{' Enumerators ',' '}' { () }
Enumerators :: { [()] }
Enumerators
: Enumerator { [$1] }
| Enumerators ',' Enumerator { $3 : $1 }
Enumerator :: { () }
Enumerator
: ID_CONST { () }
| ID_CONST '=' ConstExpr { () }
AggregateDecl :: { () }
AggregateDecl
: AggregateType ';' { () }
| typedef AggregateType ID_SUE_TYPE ';' { () }
AggregateType :: { () }
AggregateType
: struct ID_SUE_TYPE '{' MemberDecls '}' { () }
| union ID_SUE_TYPE '{' MemberDecls '}' { () }
MemberDecls :: { [()] }
MemberDecls
: MemberDecl { [$1] }
| MemberDecls MemberDecl { $2 : $1 }
MemberDecl :: { () }
MemberDecl
: QualType DeclSpec(ConstExpr) ';' { () }
| PreprocIfdef(MemberDecls) { () }
TypedefDecl :: { () }
TypedefDecl
: typedef QualType ID_SUE_TYPE ';' { () }
| typedef FunctionPrototype(ID_FUNC_TYPE) ';' { () }
QualType :: { () }
QualType
: Type { () }
| const Type { () }
Type :: { () }
Type
: LeafType { () }
| Type '*' { () }
| Type const { () }
LeafType :: { () }
LeafType
: struct ID_SUE_TYPE { () }
| void { () }
| ID_FUNC_TYPE { () }
| ID_STD_TYPE { () }
| ID_SUE_TYPE { () }
FunctionDecl :: { () }
FunctionDecl
: FunctionPrototype(ID_VAR) FunctionBody { () }
| static FunctionPrototype(ID_VAR) FunctionBody { () }
FunctionPrototype(id)
: QualType id FunctionParamList { () }
FunctionBody :: { () }
FunctionBody
: ';' { () }
| CompoundStmt { () }
FunctionParamList :: { () }
FunctionParamList
: '(' void ')' { () }
| '(' FunctionParams ')' { () }
| '(' FunctionParams ',' '...' ')' { () }
FunctionParams :: { [()] }
FunctionParams
: FunctionParam { [$1] }
| FunctionParams ',' FunctionParam { $3 : $1 }
FunctionParam :: { () }
FunctionParam
: QualType DeclSpec(ConstExpr) { () }
ConstDecl :: { () }
ConstDecl
: extern const LeafType ID_VAR ';' { () }
| const LeafType ID_VAR '=' InitialiserExpr ';' { () }
| static const LeafType ID_VAR '=' InitialiserExpr ';' { () }
{
parseError :: Lexeme -> Alex a
parseError = fail . show
lexwrap :: (Lexeme -> Alex a) -> Alex a
lexwrap = (alexMonadScan >>=)
}