/*
* 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
;
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;
}