 
/*
 * bcpl syntax
 */
digit = [0-9];
letter = [a-zA-Z_];
name = letter (letter|digit)*;
integer = [123456789]digit*;
hexdigit = [0-9a-fA-F];
octal = #[0-7][0-7]*;
hex = #[xX]hexdigit*;
realdigits = integer "." [0-9]*
|       "." [0-9][0-9]*
;
real = realdigits ("e" ([+-]|"") integer | "");
any = [\n\t \014];
illegal = [^a-zA-Z\n\t \014#+-*/^%0-9~!=<>:'"&|()[\]{}`@?,.];
%%
AND     {return(AND);}
BE      {return(BE);}
BREAK   {return(BREAK);}
BY      {return(BY);}
CASE    {return(CASE);}
DO      {return(DO);}
DEFAULT {return(DEFAULT);}
EQ      {return('=');}
EQV     {return(EQV);}
ELSE    {return(OR);}
ENDCASE {return(ENDCASE);}
FALSE   {return(FALSE);}
FOR     {return(FOR);}
FINISH  {return(FINISH);}
GOTO    {return(GOTO);}
GE      {return(GE);}
GR      {return('>');}
GLOBAL  {return(GLOBAL);}
GET     {return(GET);}
IF      {return(IF);}
INTO    {return(INTO);}
LET     {return(LET);}
LV      {return('@');}
LE      {return(LE);}
LS      {return('<');}
LOGOR   {return('|');}
LOGAND  {return('&');}
LOOP    {return(LOOP);}
LSHIFT  {return(LSHIFT);}
MANIFEST        {return(MANIFEST);}
NE      {return(NE);}
NOT     {return('~');}
NEQV    {return(NEQV);}
OR      {return(OR);}
RESULTIS        {return(RESULTIS);}
RETURN  {return(RETURN);}
REM     {return(REM);}
RSHIFT  {return(RSHIFT);}
RV      {return('!');}
REPEAT  {return(REPEAT);}
REPEATWHILE     {return(REPEATWHILE);}
REPEATUNTIL     {return(REPEATUNTIL);}
SWITCHON        {return(SWITCHON);}
STATIC  {return(STATIC);}
TO      {return(TO);}
 
TEST    {return(TEST);}
TRUE    {return(TRUE);}
THEN    {return(THEN);}
TABLE   {return(TABLE);}
UNTIL   {return(UNTIL);}
UNLESS  {return(UNLESS);}
VEC     {return(VEC);}
VALOF   {return(VALOF);}
WHILE   {return(WHILE);}
 
name    {
                gettoken(token, sizeof token);
                lexval = lookup(token, 0);
                return(IDENTIFIER);
        }
hex     {return(number(16));}
octal   {return(number(8));}
integer {return(number(10));}
 
"<"     {single: return(*token(0));}
">"     {goto single;}
"%"     {goto single;}
"/"     {goto single;}
"*"     {goto single;}
"&"     {goto single;}
"|"     {goto single;}
"^"     {goto single;}
"+"     {goto single;}
"-"     {goto single;}
"!"     {goto single;}
"@"     {goto single;}
"~"     {goto single;}
"("     {goto single;}
")"     {goto single;}
"{"     {goto single;}
"}"     {goto single;}
":"     {goto single;}
";"     {goto single;}
","     {goto single;}
 
":="    {return(GETS);}
"<="    {return(LE);}
"~="    {return(NE);}
">="    {return(GE);}
"<<"    {return(LS);}
">>"    {return(RS);}
"&&"    {return('&');}
"||"    {return('|');}
"$("    {return('{');}
"$)"    {return('}');}
"->"    {return(ARROW);}
 
"+:="   {return(ASPLUS);}
"-:="   {return(ASMINUS);}
"/:="   {return(ASDIV);}
"REM:=" {return(ASMOD);}
"*:="   {return(ASTIMES);}
"<<:="  {return(ASLSHIFT);}
">>:="  {return(ASRSHIFT);}
"|:="   {return(ASOR);}
"&:="   {return(ASAND);}
"NEQV:="        {return(ASEXOR);}
 
 
"/*"    {comment("*/");}
"'"     {;}
"\""    {
                lexval = calloc(2, sizeof lexval);
                string(lexval);
                return(STRING);
        }
any     {
                gettoken(token, sizeof token);
                c = *token;
                if (c=='\n')
                        yyline++;
        }
%%
 
number(radix)
{
        long l;
        char digits[30];
 
        gettoken(digits, sizeof digits);
        l = integ(digits, radix);
        return(l);
}
