Lex / Yacc Grammar

gram.y

/*
 * Copyright (c) 1997 Ross Cunniff
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
%{
extern void yyerror(char *);
extern int yylex(void);
%}

/* Multicharacter reserved words */
%token T_ASSERT    T_BREAK    T_CASE     T_CATCH    T_CLASS
%token T_CONST     T_CONTINUE T_DEFAULT  T_DO       T_ELSE
%token T_EXTERN    T_FOR      T_FORALL   T_IF       T_MATCH
%token T_NAMESPACE T_NEW      T_OPERATOR T_PROC
%token T_PROTECTED T_PUBLIC   T_RETURN   T_SWITCH   T_THROW
%token T_TRY       T_USING    T_VAR      T_WHILE    T_WITH
%token T_STATIC    T_LOOPBASE

%token T_FOREACH

/* Preprocessor symbols */
%token T_DEFINE T_INCLUDE

/* Other multicharacter tokens */
%token T_NAME T_INTCON T_FLOATCON T_STRING T_CHARCON T_MATCH_ARG
%token T_LCHARCON T_LSTRING

/* Punctuation */
%token T_SEMI T_COMMA T_EQUALS T_LBRACE T_RBRACE T_LPAR T_RPAR T_OR T_XOR 
%token T_AND T_LT T_GT T_PLUS T_MINUS T_STAR T_SLASH T_PCT T_NOT T_BANG 
%token T_DOT T_LBRAK T_RBRAK T_COLON T_AT T_QUEST T_STARSTAR T_BACKTICK

/* Two-char punctuation */
%token T_CONCAT T_EQEQ T_NOTEQ T_LE T_GE T_PLUSEQ T_MINUSEQ T_STAREQ 
%token T_SLASHEQ T_PCTEQ T_ANDEQ T_OREQ T_XOREQ T_LSHIFT T_RSHIFT 
%token T_ANDAND T_OROR T_PLUSPLUS T_MINUSMINUS T_EQGT T_QUEST_EQ
%token T_MATCHES T_MATCH_COUNT T_COLON_COLON T_HASH_EQ T_AT_AT
%token T_HASH_LBRAK T_HASH_LPAR T_QUEST_QUEST T_COLON_EQUALS
%token T_HASH_LBRACE

/* Three-char punctuation */
%token T_LSHIFTEQ T_RSHIFTEQ T_LLL T_RRR T_DOTDOTDOT

/* "Reverse" punctuation */
%token T_OR_R T_XOR_R T_AND_R T_LT_R T_GT_R T_PLUS_R T_MINUS_R T_BANG_MINUS
%token T_STAR_R T_SLASH_R T_PCT_R T_POW_R T_EQEQ_R T_NOTEQ_R T_LE_R T_GE_R
%token T_LSHIFT_R T_RSHIFT_R T_EQGT_R T_MATCHES_R

/* End-of-file marker */
%token T_EOF 

/* Handle the dangling else shift/reduce conflict */
%nonassoc T_THEN
%nonassoc T_ELSE

/* Handle the dangling :: shift/reduce conflict */
%nonassoc T_NAME
%nonassoc T_COLON_COLON

%%

program         : prog T_EOF { return 0; }
                ;

prog            : decl
                | prog decl
                ;

decl            : class_decl
                | var_decl
                | proc_decl
                | const_decl
                | include
                | using
                | define
                | public_decl
                | default_public
                | extern_decl
                | obj_decl
                | T_NAMESPACE T_NAME T_LBRACE prog T_RBRACE
                ;

class_decl      : T_CLASS qual_name proplist
                | T_CLASS qual_name T_LPAR qual_names T_RPAR proplist
                | T_CLASS qual_names T_SEMI
                ;

proplist        : T_LBRACE props T_RBRACE
                ;

props           : /* NOTHING */
                | props prop
                ;

prop            : T_PUBLIC oneprop
                | T_PROTECTED oneprop
                | oneprop
                ;

oneprop         : var_decl
                | const_decl
                | proc_decl
                | T_OPERATOR oper_decl
                ;

var_decl        : T_VAR vars T_SEMI
                | T_STATIC vars T_SEMI
                ;

vars            : var
                | vars T_COMMA var
                ;

var             : qual_name
                | qual_name T_EQUALS expr
                | qual_name T_COLON type 
                | qual_name T_COLON type T_EQUALS expr
                ;

type            : T_NAME
                | T_NAME T_LBRAK exprlist T_RBRAK
                | T_NAME T_LBRAK T_STAR T_RBRAK
                ;

const_decl      : T_CONST consts T_SEMI
                ;

consts          : name_init
                | consts T_COMMA name_init
                ;

name_init       : qual_name T_EQUALS expr
                ;

oper_decl       : operator no_name_proc
                ;

operator        : T_OR | T_XOR | T_AND | T_LT | T_GT
                | T_PLUS | T_MINUS | T_STAR | T_SLASH | T_STARSTAR
                | T_PCT | T_NOT | T_CONCAT | T_EQEQ
                | T_NOTEQ | T_LE | T_GE | T_LSHIFT | T_RSHIFT
                | T_LBRACE T_RBRACE
                | T_LBRAK T_RBRAK | T_LBRAK T_EQUALS T_RBRAK
                | T_HASH_LBRAK T_RBRAK | T_HASH_LBRAK T_EQUALS T_RBRAK
                | T_LPAR T_RPAR | T_EQGT | T_MATCHES
                | T_PLUSPLUS | T_MINUSMINUS
                | T_OR_R | T_XOR_R | T_AND_R | T_LT_R | T_GT_R | T_PLUS_R
                | T_MINUS_R | T_BANG_MINUS | T_STAR_R | T_SLASH_R | T_PCT_R
                | T_POW_R | T_EQEQ_R | T_NOTEQ_R | T_LE_R | T_GE_R
                | T_LSHIFT_R | T_RSHIFT_R | T_EQGT_R | T_MATCHES_R
                | T_COLON_EQUALS
                ;

include         : T_INCLUDE T_STRING
                ;

using           : T_USING using_decls T_SEMI
                ;

using_decls     : one_use
                | using_decls T_COMMA one_use
                ;

one_use         : T_NAMESPACE T_NAME
                | T_EXTERN T_STRING
                | qual_name
                ;

define          : T_DEFINE T_NAME T_LPAR names T_RPAR T_LBRACE defn T_RBRACE
                | T_DEFINE T_NAME T_LPAR T_RPAR T_LBRACE defn T_RBRACE
                ;

defn            : /* NOTHING */
                | defn token
                | defn T_LPAR defn T_RPAR
                | defn T_LBRACE defn T_RBRACE
                | defn T_LBRAK defn T_RBRAK
                | defn T_HASH_LBRAK defn T_RBRAK
                | defn T_HASH_LPAR defn T_RBRAK
                ;

token           : T_CLASS | T_VAR | T_CONST | T_PUBLIC
                | T_PROC | T_IF | T_ELSE | T_WHILE
                | T_BREAK | T_RETURN | T_INCLUDE | T_SWITCH
                | T_CASE | T_DEFAULT | T_FOR | T_DO | T_FORALL
                | T_CONTINUE | T_NEW | T_OPERATOR | T_PROTECTED
                | T_TRY | T_CATCH | T_THROW | T_ASSERT
                | T_DEFINE | T_NAME | T_INTCON | T_FLOATCON
                | T_STRING | T_CHARCON | T_LSTRING | T_LCHARCON
                | T_SEMI | T_COMMA | T_EQUALS | T_OR
                | T_XOR | T_AND | T_LT | T_GT
                | T_PLUS | T_MINUS | T_STAR | T_SLASH | T_STARSTAR
                | T_PCT | T_NOT | T_BANG | T_DOT
                | T_COLON | T_AT | T_CONCAT | T_EQEQ
                | T_NOTEQ | T_LE | T_GE | T_PLUSEQ
                | T_MINUSEQ | T_STAREQ | T_SLASHEQ | T_PCTEQ
                | T_ANDEQ | T_OREQ | T_XOREQ | T_LSHIFT
                | T_RSHIFT | T_ANDAND | T_OROR | T_PLUSPLUS
                | T_MINUSMINUS | T_EQGT | T_QUEST_EQ | T_LSHIFTEQ
                | T_RSHIFTEQ  | T_MATCH | T_MATCHES | T_MATCH_ARG
                | T_MATCH_COUNT | T_USING | T_NAMESPACE
                | T_QUEST | T_COLON_COLON | T_WITH | T_EXTERN
                | T_HASH_EQ | T_AT_AT | T_QUEST_QUEST
                | T_OR_R | T_XOR_R | T_AND_R | T_LT_R | T_GT_R | T_PLUS_R
                | T_MINUS_R | T_BANG_MINUS | T_STAR_R | T_SLASH_R | T_PCT_R
                | T_POW_R | T_EQEQ_R | T_NOTEQ_R | T_LE_R | T_GE_R
                | T_LSHIFT_R | T_RSHIFT_R | T_EQGT_R | T_MATCHES_R
                | T_COLON_EQUALS
                ;

public_decl     : T_PUBLIC names T_SEMI
                ;

default_public  : T_DEFAULT T_PUBLIC consts T_SEMI
                ;

extern_decl     : T_EXTERN names T_SEMI
                ;

names           : T_NAME
                | names T_COMMA T_NAME
                ;

qual_names      : qual_name
                | qual_names T_COMMA qual_name
                ;

obj_decl        : obj_decl_list T_SEMI
                | obj_decl_props
                ;

obj_decl_list   : obj_decl_noprop
                | obj_decl T_COMMA obj_decl_noprop
                ;

obj_decl_noprop : qual_name qual_name
                | qual_name qual_name T_LPAR exprs T_RPAR
                ;

obj_decl_props  : qual_name qual_name obj_proplist
                | qual_name qual_name T_LPAR exprs T_RPAR obj_proplist
                | T_DOTDOTDOT qual_name obj_proplist
                ;

obj_proplist    : T_LBRACE obj_props T_RBRACE
                | T_LBRACE obj_props T_DOTDOTDOT T_RBRACE
                ;

obj_props       : /* NOTHING */
                | obj_props prop_init
                ;

prop_init       : T_NAME T_EQUALS expr
                ;

proc_decl       : T_PROC qual_name T_LPAR args T_RPAR proc_body
                | T_PROC qual_name T_LPAR T_RPAR proc_body
                | T_PROC T_STRING qual_name T_LPAR args T_RPAR proc_body
                | T_PROC T_STRING qual_name T_LPAR T_RPAR proc_body
                | T_PROC qual_names T_SEMI
                ;

args            : T_NAME
                | T_NAME T_COLON type
                | args T_COMMA T_NAME
                | args T_COMMA T_NAME T_COLON type
                ;

no_name_proc    : T_LPAR names T_RPAR proc_body
                | T_LPAR T_RPAR proc_body
                ;

proc_body       : T_LBRACE stmts T_RBRACE
                | T_COLON type T_LBRACE stmts T_RBRACE
                ;

stmts           : /* NOTHING */
                | stmt stmts
                ;

stmt            : assign T_SEMI
                | call T_SEMI
                | ifstmt
                | whilestmt
                | dostmt T_SEMI
                | forstmt
                | forallstmt
                | switchstmt
                | matchstmt
                | withstmt
                | returnstmt T_SEMI
                | assertstmt T_SEMI
                | trystmt
                | throwstmt T_SEMI
                | breakstmt T_SEMI
                | continuestmt T_SEMI
                | var_decl
                | const_decl
                | using
                | printstmt T_SEMI
                ;

assign          : lhs T_EQUALS expr
                | lhs T_PLUSEQ expr
                | lhs T_MINUSEQ expr
                | lhs T_STAREQ expr
                | lhs T_SLASHEQ expr
                | lhs T_PCTEQ expr
                | lhs T_ANDEQ expr
                | lhs T_OREQ expr
                | lhs T_XOREQ expr
                | lhs T_LSHIFTEQ expr
                | lhs T_RSHIFTEQ expr
                | lhs T_PLUSPLUS
                | lhs T_MINUSMINUS
                ;

call            : lhs T_LPAR exprs T_RPAR
                | lhs T_HASH_LPAR exprs T_RPAR
                ;

lhs             : qual_name
                | lhs T_DOT T_NAME
                | lhs T_DOT T_LPAR expr T_RPAR
                | lhs T_LBRAK indices T_RBRAK
                | lhs T_HASH_LBRAK indices T_RBRAK
                | T_LPAR lhs T_RPAR
                ;

ifstmt          : T_IF T_LPAR expr T_RPAR body                  %prec T_THEN
                | T_IF T_LPAR expr T_RPAR body T_ELSE body
                ;

whilestmt       : T_WHILE T_LPAR expr T_RPAR body
                ;

dostmt          : T_DO body T_WHILE T_LPAR expr T_RPAR
                ;

forstmt         : T_FOR T_LPAR alst T_SEMI limit T_SEMI alst T_RPAR body
                ;

forallstmt      : T_FORALL T_LPAR expr T_RPAR body
                ;

alst            : /* NOTHING */
                | assign_list
                ;

assign_list     : one_assign
                | assign_list T_COMMA one_assign
                ;

one_assign      : assign
                | lhs
                | T_VAR T_NAME T_EQUALS expr
                | T_VAR T_NAME T_COLON T_NAME T_EQUALS expr
                | T_STATIC T_NAME T_EQUALS expr
                | T_STATIC T_NAME T_COLON T_NAME T_EQUALS expr
                ;

limit           : /* NOTHING */
                | expr
                ;

switchstmt      : T_SWITCH T_LPAR expr T_RPAR T_LBRACE cases T_RBRACE
                ;

matchstmt       : T_MATCH T_LPAR expr T_RPAR T_LBRACE cases T_RBRACE
                ;

cases           : /* NOTHING */
                | cases onecase
                ;

onecase         : T_CASE exprlist T_COLON stmts
                | T_DEFAULT T_COLON stmts
                ;

returnstmt      : T_RETURN expr
                | T_RETURN
                ;

assertstmt      : T_ASSERT expr
                ;

withstmt        : T_WITH T_LPAR expr T_RPAR T_LBRACE obj_props T_RBRACE
                ;

trystmt         : T_TRY body T_CATCH T_LPAR names T_RPAR body
                ;

throwstmt       : T_THROW expr
                ;

breakstmt       : T_BREAK
                ;

continuestmt    : T_CONTINUE
                ;

printstmt       : T_STRING
                | T_STRING T_COMMA exprs
                | T_LSTRING
                | T_LSTRING T_COMMA exprs
                ;

body            : T_LBRACE stmts T_RBRACE
                | stmt
                ;

exprs           : /* NOTHING */
                | exprlist
                ;

exprlist        : expr
                | exprlist T_COMMA expr
                ;

expr            : cond_expr
                | expr T_CONCAT cond_expr
                ;

cond_expr       : logor_expr
                | logor_expr T_QUEST expr T_COLON cond_expr
                ;

logor_expr      : logand_expr
                | logor_expr T_OROR logand_expr
                ;

logand_expr     : or_expr
                | logand_expr T_ANDAND or_expr
                ;

or_expr         : excl_or_expr
                | or_expr T_OR excl_or_expr
                ;

excl_or_expr    : and_expr
                | excl_or_expr T_XOR and_expr
                ;

and_expr        : equal_expr
                | and_expr T_AND equal_expr
                ;

equal_expr      : rel_expr
                | equal_expr T_EQEQ rel_expr
                | equal_expr T_NOTEQ rel_expr
                | equal_expr T_QUEST_EQ rel_expr
                | equal_expr T_MATCHES rel_expr
                | equal_expr T_HASH_EQ rel_expr
                ;

rel_expr        : shift_expr
                | rel_expr T_LT shift_expr
                | rel_expr T_GT shift_expr
                | rel_expr T_LE shift_expr
                | rel_expr T_GE shift_expr
                ;

shift_expr      : add_expr
                | shift_expr T_LSHIFT add_expr
                | shift_expr T_RSHIFT add_expr
                ;

add_expr        : mult_expr
                | add_expr T_PLUS mult_expr
                | add_expr T_MINUS mult_expr
                ;

mult_expr       : pow_expr
                | mult_expr T_STAR pow_expr
                | mult_expr T_SLASH pow_expr
                | mult_expr T_PCT pow_expr
                ;

pow_expr        : cvt_expr
                | cvt_expr T_STARSTAR pow_expr
                ;

cvt_expr        : unary_expr
                | cvt_expr T_EQGT unary_expr
                ;

unary_expr      : T_NOT unary_expr
                | T_BANG unary_expr
                | T_MINUS unary_expr
                | T_AT unary_expr
                | T_AT_AT unary_expr
                | T_QUEST_QUEST unary_expr
                | T_AND T_NAME
                | term
                ;

indices         : index
                | indices T_COMMA index
                ;

index           : expr
                | opt_expr T_COLON opt_expr
                | opt_expr T_COLON opt_expr T_COLON expr
                ;

qual_name       : T_NAME
                | T_NAME T_COLON_COLON T_NAME
                | T_COLON_COLON T_NAME
                ;

term            : qual_name
                | T_PUBLIC T_COLON_COLON T_NAME
                | T_LPAR expr T_RPAR
                | T_LPAR T_PROC T_RPAR          /* ID of current proc */
                | T_LBRACE exprs T_RBRACE       /* Array decl */
                | T_HASH_LBRACE exprs T_RBRACE  /* Multimensional array decl */
                | T_LLL exprs T_RRR             /* Dict decl */
                | T_LBRAK exprs T_RBRAK         /* Packed array decl */
                | T_LBRAK iterator T_RBRAK      /* Iterator */
                | T_STRING
                | T_LSTRING
                | T_INTCON
                | T_FLOATCON
                | T_CHARCON
                | T_LCHARCON
                | T_MATCH_ARG
                | T_MATCH_COUNT
                | T_LOOPBASE
                | T_NEW qual_name               /* The create args are parsed */
                | T_NEW T_LPAR expr T_RPAR      /* by the CALL syntax below */
                | T_PROC no_name_proc
                | T_PROC T_STRING no_name_proc
                | T_OPERATOR operator
                | T_BACKTICK operator
                | T_BACKTICK T_NAME             /* Same as public::name */
                | term T_LPAR exprs T_RPAR      /* This is the CALL syntax */
                | term T_LBRAK T_STAR T_RBRAK     /* For "Array[*]" */
                | term T_HASH_LPAR exprs T_RPAR
                | term T_DOT public
                | term T_LBRAK indices T_RBRAK
                | term T_HASH_LBRAK indices T_RBRAK
                | term T_LBRACE obj_props T_RBRACE /* For new and static obj */
                | T_FOREACH T_LPAR expr T_RPAR T_LBRACE expr T_RBRACE
                ;

iterator        : opt_expr T_COLON opt_expr
                | opt_expr T_COLON opt_expr T_COLON opt_expr
                ;

opt_expr        : /* NOTHING */
                | expr
                ;

public          : T_NAME
                | T_LPAR expr T_RPAR
                | T_OPERATOR operator
                | T_BACKTICK operator
                | T_BACKTICK T_NAME
                ;

gram.l

The following lex / bison program properly tokenizes correct OADL programs:

/*
 * Copyright (c) 1997 Ross Cunniff
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

%{
#include "y.tab.h"
#define YY_NO_UNISTD_H
int line_num = 1;
%}

%x str
%x comment

/* This is a major hack. Rather than try to hand-enumerate all the possible
 * UTF-8 encodings of letter and digit characters, just assume that all
 * multibyte encodings are, effectively, letter characters. This
 * will accept valid programs but will not properly error on invalid
 * ones.
 */
U       [\x80-\xbf]
U2      [\xc2-\xdf]
U3      [\xe0-\xef]
U4      [\xf0-\xf7]

UANY    {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}

ALPHA           [a-zA-Z$_]|{UANY}
ALNUM           [0-9a-zA-Z$_]|{UANY}

DIGIT           [0-9_]
HEXDIGIT        [0-9a-fA-F_]
ESCAPE          [0abfnrtv]
ISIZE           [ubslUBSL]
FSIZE           [hdHD]

%%

L\"                             BEGIN(str);
\"                              BEGIN(str);
<str>\"                         BEGIN(INITIAL); return T_STRING;
<str>\\[0-7]{1,3}
<str>\\0[xX]HEXDIGIT+
<str>\\(.|\n)
<str>[^\\\n\"]+

L\'.\'          return T_LCHARCON;
\'.\'           return T_CHARCON;
\'\\.\'         return T_CHARCON;


{DIGIT}+{ISIZE}*                        return T_INTCON;
"0"[xX]{HEXDIGIT}+{ISIZE}*              return T_INTCON;

{DIGIT}+"."{DIGIT}*{FSIZE}*                 return T_FLOATCON;
{DIGIT}*"."{DIGIT}+{FSIZE}*                 return T_FLOATCON;
{DIGIT}+"."{DIGIT}*[eE]{DIGIT}+{FSIZE}*     return T_FLOATCON;
{DIGIT}*"."{DIGIT}+[eE]{DIGIT}+{FSIZE}*     return T_FLOATCON;
{DIGIT}+"."{DIGIT}*[eE][+-]{DIGIT}+{FSIZE}* return T_FLOATCON;
{DIGIT}*"."{DIGIT}+[eE][+-]{DIGIT}+{FSIZE}* return T_FLOATCON;
{DIGIT}+[eE]{DIGIT}+{FSIZE}*                return T_FLOATCON;
{DIGIT}+[eE][+-]{DIGIT}+{FSIZE}*            return T_FLOATCON;

"?"{DIGIT}+                             return T_MATCH_ARG;

case            return T_CASE;
continue        return T_CONTINUE;
default         return T_DEFAULT;
do              return T_DO;
else            return T_ELSE;
extern          return T_EXTERN;
for             return T_FOR;
forall          return T_FORALL;
foreach         return T_FOREACH;
if              return T_IF;
return          return T_RETURN;
switch          return T_SWITCH;
while           return T_WHILE;
break           return T_BREAK;
class           return T_CLASS;
var             return T_VAR;
const           return T_CONST;
public          return T_PUBLIC;
proc            return T_PROC;
"#include"      return T_INCLUDE;
new             return T_NEW;
operator        return T_OPERATOR;
protected       return T_PROTECTED;
try             return T_TRY;
catch           return T_CATCH;
throw           return T_THROW;
assert          return T_ASSERT;
"#define"       return T_DEFINE;
match           return T_MATCH;
using           return T_USING;
namespace       return T_NAMESPACE;
with            return T_WITH;
static          return T_STATIC;

{ALPHA}{ALNUM}* return T_NAME;

";"     return T_SEMI;
","     return T_COMMA;
"="     return T_EQUALS;
"{"     return T_LBRACE;
"}"     return T_RBRACE;
"("     return T_LPAR;
")"     return T_RPAR;
"|"     return T_OR;
"^"     return T_XOR;
"&"     return T_AND;
"<"     return T_LT;
">"     return T_GT;
"+"     return T_PLUS;
"-"     return T_MINUS;
"*"     return T_STAR;
"/"     return T_SLASH;
"%"     return T_PCT;
"~"     return T_NOT;
"!"     return T_BANG;
"."     return T_DOT;
"["     return T_LBRAK;
"]"     return T_RBRAK;
":"     return T_COLON;
"@"     return T_AT;
"?"     return T_QUEST;
"`"     return T_BACKTICK;

"**"    return T_STARSTAR;
"##"    return T_CONCAT;
"=="    return T_EQEQ;
"!="    return T_NOTEQ;
"<="    return T_LE;
">="    return T_GE;
"+="    return T_PLUSEQ;
"-="    return T_MINUSEQ;
"*="    return T_STAREQ;
"/="    return T_SLASHEQ;
"%="    return T_PCTEQ;
"&="    return T_ANDEQ;
"|="    return T_OREQ;
"^="    return T_XOREQ;
"<<"    return T_LSHIFT;
">>"    return T_RSHIFT;
"&&"    return T_ANDAND;
"||"    return T_OROR;
"++"    return T_PLUSPLUS;
"--"    return T_MINUSMINUS;
"=>"    return T_EQGT;
"?="    return T_QUEST_EQ;
"??"    return T_QUEST_QUEST;
"~="    return T_MATCHES;
"?#"    return T_MATCH_COUNT;
"::"    return T_COLON_COLON;
"@@"    return T_AT_AT;
"#="    return T_HASH_EQ;
"#["    return T_HASH_LBRAK;
"#("    return T_HASH_LPAR;
"#{"    return T_HASH_LBRACE;
"?*"    return T_LOOPBASE;
"!-"    return T_BANG_MINUS;
"->"    return T_DOT;
":="    return T_COLON_EQUALS;

"\\|"   return T_OR_R;
"\\^"   return T_XOR_R;
"\\&"   return T_AND_R;
"\\<"   return T_LT_R;
"\\>"   return T_GT_R;
"\\+"   return T_PLUS_R;
"\\-"   return T_MINUS_R;
"\\*"   return T_STAR_R;
"\\/"   return T_SLASH_R;
"\\%"   return T_PCT_R;
"\\**"  return T_POW_R;
"\\=="  return T_EQEQ_R;
"\\!="  return T_NOTEQ_R;
"\\<="  return T_LE_R;
"\\>="  return T_GE_R;
"\\<<"  return T_LSHIFT_R;
"\\>>"  return T_RSHIFT_R;
"\\=>"  return T_EQGT_R;
"\\~="  return T_MATCHES_R;

"<<="   return T_LSHIFTEQ;
">>="   return T_RSHIFTEQ;
"<<<"   return T_LLL;
">>>"   return T_RRR;
"..."   return T_DOTDOTDOT;

<<EOF>> return T_EOF;

"//".*\n                line_num++;
"/*"                    BEGIN(comment);
<comment>[^*\n]*
<comment>"*"+[^*/\n]*
<comment>\n             line_num++;
<comment>"*"+"/"        BEGIN(INITIAL);

"/*".*"*/"
[ \t\r]+
\n                      line_num++;

%%

extern int yydebug;
extern int yyparse(void);

int main(int argc, char **argv)
{
    if( (argc > 1) && (strcmp(argv[1], "-d") == 0) ) {
        yydebug = 1;
    }

    if( yyparse() == 0 ) {
        printf("success!\n");
    }
}

void yyerror(char *s)
{
    printf("failure at line %d\n", line_num);
    exit(1);
}

int yywrap(void)
{
    return 1;
}

Back to OADL Implementation Notes

Return to Introduction