%{
#include <string.h>
-#include "q.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include "../lib/q.h"
#include "parser.h"
//RVALUE {NUMBER}|{PERCENT}|{NAME}|\"{STRING}\"|{DIM}
static void unescapeString(string_t * tmp)
{
char *p, *p1;
+ /* fixme - this routine expects the string to be
+ null-terminated */
- for (p1=tmp->str; (p=strchr(p1, '\\')) != 0; p1 = p+1)
+ for (p1=tmp->str; (p=strchr(p1, '\\')); p1 = p+1)
{
switch(p[1])
{
- case '\\': p[1] = '\\'; break;
- case 'b': p[1] = '\b'; break;
- case 'f': p[1] = '\f'; break;
- case 'n': p[1] = '\n'; break;
- case 'r': p[1] = '\r'; break;
- case 't': p[1] = '\t'; break;
+ case '\\': p[1] = '\\'; tmp->len--; break;
+ case '"': p[1] = '"'; tmp->len--; break;
+ case 'b': p[1] = '\b'; tmp->len--; break;
+ case 'f': p[1] = '\f'; tmp->len--; break;
+ case 'n': p[1] = '\n'; tmp->len--; break;
+ case 'r': p[1] = '\r'; tmp->len--; break;
+ case 't': p[1] = '\t'; tmp->len--; break;
default:
continue;
}
}
prefix = 0;
break;
- case LABEL:
- string_set2(&tmp, text, length-1);
+ case RAWDATA:
+ string_set2(&tmp, text+1/*:*/, length-5/*.end*/);
token.text = (char*)mem_putstring(&strings, tmp);
break;
case COMMAND:
prefix = 0;
}
+#define MAX_INCLUDE_DEPTH 16
+YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
+int line_stack[MAX_INCLUDE_DEPTH];
+int column_stack[MAX_INCLUDE_DEPTH];
+int include_stack_ptr = 0;
+
+void handleInclude(char*text, int len)
+{
+ text+=9;len-=9;
+ while(len >=1 && (text[0] == ' ' || text[0] == '\t')) {
+ text++;len--;
+ }
+ while(len >= 1 && (text[len-1] == ' ' || text[len-1] == '\n')) {
+ len--;
+ }
+ if(len >= 2 && text[0] == '"' && text[len-1] == '"') {
+ text++; len-=2;
+ }
+ text[len] = 0;
+ if(include_stack_ptr >= MAX_INCLUDE_DEPTH) {
+ fprintf( stderr, "Includes nested too deeply" );
+ exit( 1 );
+ }
+ include_stack[include_stack_ptr] = YY_CURRENT_BUFFER;
+ line_stack[include_stack_ptr] = line;
+ column_stack[include_stack_ptr] = column;
+ include_stack_ptr++;
+ yyin = fopen(text, "rb");
+ if (!yyin) {
+ fprintf(stderr, "Couldn't open %s\n", text);
+ exit(1);
+ }
+ yy_switch_to_buffer(
+ yy_create_buffer( yyin, YY_BUF_SIZE ) );
+ BEGIN(INITIAL);
+}
+
#define c() {count(yytext, yyleng, YY_START);}
#define s(type) {store(type, line, column, yytext, yyleng);}
%}
%x BINARY
NAME [a-zA-Z_./](-*[a-zA-Z0-9_./])*
-TWIP ([0-9]+(\.([0-9]([05])?)?)?)
-NUMBER [0-9]+(\.[0-9]*)?
+TWIP (-?[0-9]+(\.([0-9]([05])?)?)?)
+NUMBER -?[0-9]+(\.[0-9]*)?
PERCENT {NUMBER}%
STRING (\\.|[^\\"\n])*
S [ \n\r\t]
{NAME}{S}*-= {s(ASSIGNMENT);prefix="<minus>";c();BEGIN(R);}
{NAME}{S}*= {s(ASSIGNMENT);c();BEGIN(R);}
<R>{ /* values which appear only on the right-hand side of assignments, like: x=50% */
- [^ \n\t\r]* {s(IDENTIFIER);c();BEGIN(0);}
+ [^ :\n\t\r]* {s(IDENTIFIER);c();BEGIN(0);}
}
+\.include{S}.*\n {handleInclude(yytext, yyleng);}
\.{NAME} {s(COMMAND);c();}
-{NAME}{S}*: {s(LABEL);c();}
+:([^.]|\.[^e]|\.e[^n]|\.en[^d]|[ \n\r\t])*\.end {s(RAWDATA);c();}
{NAME} {s(IDENTIFIER);c();}
"[" {c();BEGIN(BINARY);}
{S} {c();}
-. {char c,c1=0;
+. {char c,c1=yytext[0];
printf("Syntax error in line %d, %d: %s", line, column, yytext);
while(1) {
c=input();
- if(!c1) c1=c;
if(c=='\n' || c==EOF)
break;
printf("%c", c);
exit(1);
yyterminate();
}
-<<EOF>> {c();s(END);yyterminate();}
+<<EOF>> {c();
+ if ( --include_stack_ptr < 0 ) {
+ s(END);
+ yyterminate();
+ } else {
+ yy_delete_buffer( YY_CURRENT_BUFFER );
+ yy_switch_to_buffer(
+ include_stack[include_stack_ptr] );
+ column = column_stack[include_stack_ptr];
+ line = line_stack[include_stack_ptr];
+ }
+ }
+
%%
int yywrap()