deelang/lexer.l

67 lines
1.4 KiB
Plaintext

%{
#include "parser.h"
int stack[100]; // Max indentation depth
int sp = -1;
int peek();
void push(int a);
void pop();
#define YY_USER_INIT push(0); BEGIN(freshline);
%}
%option noyywrap
%x freshline
digit [0-9]
letter [A-Za-z]
%%
<freshline>""/[^\t ] {
if (peek() == 0) {
BEGIN(0);
} else {
pop(); yyless(0); return DEDENT;
}
}
<freshline>[ \t]+ {
if (peek() == yyleng) {
BEGIN(0); // Same indentation, continue
} else if (peek() > yyleng) {
pop(); yyless(0); return DEDENT;
// Same rule again until the stack is even
} else {
push(yyleng); BEGIN(0); return INDENT;
}
}
#[^\n]* // Eat comments
\"[^"]*\" yylval.sym = yytext; return STRING;
if return IF;
else return ELSE;
elif return ELIF;
{digit}+|{digit}*\.{digit}+ yylval.num = atof(yytext); return NUM;
{letter}({letter}|{digit}|[?-])* yylval.sym = yytext; return ID;
"<-" return GETS;
"->" return MAPS;
[(){}.,*/+-] return yytext[0];
[\t ] // Eat whitespace not first on a line
"/"\n // Eat newlines ending in /
[\n;] BEGIN(freshline); return STOP;
. fprintf(stderr, "Scanning error!\nOffender: %s\n", yytext); exit(1);
%%
int peek() {
printf("Peek @ %d\n", stack[sp]);
return stack[sp];
}
void push(int a) {
printf("Push @ %d\n", a);
sp++;
stack[sp] = a;
}
void pop() {
printf("Pop! Sp @ %d\n", sp);
sp--;
}