/[svn]/linuxsampler/trunk/src/scriptvm/scanner.l
ViewVC logotype

Diff of /linuxsampler/trunk/src/scriptvm/scanner.l

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2585 by schoenebeck, Sat May 31 21:09:25 2014 UTC revision 2935 by schoenebeck, Sun Jul 10 14:24:13 2016 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (c) 2014 Christian Schoenebeck and Andreas Persson   * Copyright (c) 2014-2016 Christian Schoenebeck and Andreas Persson
3   *   *
4   * http://www.linuxsampler.org   * http://www.linuxsampler.org
5   *   *
# Line 7  Line 7 
7   * See README file for details.   * See README file for details.
8   */   */
9    
10  /* Token scanner for instrument script language. */  /* Token scanner for NKSP real-time instrument script language. */
   
 /* FIXME: line numbers (i.e. on error/warning messages) are incorrect, because  
    the current grammar does not process new line characters. \n is currently  
    filtered out in this lexer. Due to this, the parser will sometimes read  
    several lines before it matches the next complete grammar rule, causing the  
    incorrect lines in the error/warning messages. */  
11    
12  %{  %{
13    
# Line 26  Line 20 
20  {                                       \  {                                       \
21      yylloc->first_line = yylineno;      \      yylloc->first_line = yylineno;      \
22      yylloc->last_line  = yylineno;      \      yylloc->last_line  = yylineno;      \
23      /* first_column = TODO */           \      yylloc->first_column = yycolumn;    \
24      /* last_column  = TODO */           \      yycolumn += yyleng;                 \
25        yylloc->last_column = yycolumn - 1; \
26      /*printf("lex: line '%s'\n", yytext);*/  \      /*printf("lex: line '%s'\n", yytext);*/  \
27  }  }
28  // custom (f)lex input for reading from std::istream object  // custom (f)lex input for reading from std::istream object
# Line 43  Line 38 
38  }  }
39    
40  static void scanner_error(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* err) {  static void scanner_error(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* err) {
41      context->addErr(locp->first_line, err);      context->addErr(locp->first_line, locp->last_line, locp->first_column, locp->last_column, err);
42  }  }
43    
44  static void scanner_warning(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* txt) {  static void scanner_warning(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* txt) {
45      context->addWrn(locp->first_line, txt);      context->addWrn(locp->first_line, locp->last_line, locp->first_column, locp->last_column, txt);
46  }  }
47    
48  #define SCANNER_ERR(txt)  scanner_error(yylloc, yyextra, txt)  #define SCANNER_ERR(txt)  scanner_error(yylloc, yyextra, txt)
# Line 55  static void scanner_warning(YYLTYPE* loc Line 50  static void scanner_warning(YYLTYPE* loc
50    
51  using namespace LinuxSampler;  using namespace LinuxSampler;
52    
53    static int countNewLineChars(const char* txt) {
54        int n = 0;
55        for (int i = 0; txt[i]; ++i)
56            if (txt[i] == '\n') ++n;
57        return n;
58    }
59    
60    static int countCharsPastLastNewLine(const char* txt) {
61        const int n = strlen(txt);
62        for (int i = n - 1; i >= 0; --i)
63            if (txt[i] == '\n')
64                return n - i - 1;
65        return n;
66    }
67    
68    #define processLocation() { \
69        const int nl = countNewLineChars(yytext); \
70        yylineno += nl; \
71        if (nl) yycolumn = countCharsPastLastNewLine(yytext); \
72    }
73    
74  %}  %}
75    
76  /* use Flex's built-in support for line numbers */  /* use Flex's built-in support for line numbers
77  %option yylineno     (disabled, because it seems to be unreliable, so we are using our own
78       tracking code in the respective scanner rules below) */
79    /*%option yylineno*/
80  /* generate a reentrant safe scanner */  /* generate a reentrant safe scanner */
81  %option reentrant  %option reentrant
82  /* avoid symbol collision with other (i.e. future) scanner symbols */  /* avoid symbol collision with other (i.e. future) scanner symbols */
# Line 78  using namespace LinuxSampler; Line 96  using namespace LinuxSampler;
96  %x PREPROC_SET_COND PREPROC_RESET_COND PREPROC_IF PREPROC_IF_NOT PREPROC_BODY_EAT PREPROC_PRE_BODY_USE PREPROC_PRE_BODY_EAT  %x PREPROC_SET_COND PREPROC_RESET_COND PREPROC_IF PREPROC_IF_NOT PREPROC_BODY_EAT PREPROC_PRE_BODY_USE PREPROC_PRE_BODY_EAT
97    
98  DIGIT    [0-9]  DIGIT    [0-9]
99  ID       [a-zA-Z0-9_]*  ID       [a-zA-Z0-9_]+
100    
101  %%  %%
102    
# Line 93  ID       [a-zA-Z0-9_]* Line 111  ID       [a-zA-Z0-9_]*
111      return INTEGER;      return INTEGER;
112  }  }
113    
114  {DIGIT}+"."{DIGIT}* {   /* there is currently no support for floating point numbers in NKSP yet */
115     /*{DIGIT}+"."{DIGIT}* {
116      printf("A float: %s (%g)\n", yytext, atof(yytext));      printf("A float: %s (%g)\n", yytext, atof(yytext));
117  }   }*/
118    
119    
120   /* Preprocessor statement:  SET_CONDITION(name) */   /* Preprocessor statement:  SET_CONDITION(name) */
121    
122  <*>"SET_CONDITION"[ \t]*"(" {  <*>"SET_CONDITION"[ \t]*"(" {
123      printf("SET_CONDITION\n");      //printf("SET_CONDITION\n");
124      yy_push_state(PREPROC_SET_COND, yyscanner);      yy_push_state(PREPROC_SET_COND, yyscanner);
125  }  }
126  <PREPROC_SET_COND>{ID} {  <PREPROC_SET_COND>{ID} {
127      printf("preproc set condition '%s'\n", yytext);      //printf("preproc set condition '%s'\n", yytext);
128      bool success = yyextra->setPreprocessorCondition(yytext);      bool success = yyextra->setPreprocessorCondition(yytext);
129      if (!success) {      if (!success) {
130          SCANNER_WRN((String("Preprocessor: Condition '") +          SCANNER_WRN((String("Preprocessor: Condition '") +
# Line 113  ID       [a-zA-Z0-9_]* Line 132  ID       [a-zA-Z0-9_]*
132      }      }
133  }  }
134  <PREPROC_SET_COND>[ \t]*")" {  <PREPROC_SET_COND>[ \t]*")" {
135      printf("End of PREPROC_SET_COND\n");      //printf("End of PREPROC_SET_COND\n");
136      yy_pop_state(yyscanner);      yy_pop_state(yyscanner);
137  }  }
138    
# Line 121  ID       [a-zA-Z0-9_]* Line 140  ID       [a-zA-Z0-9_]*
140   /* Preprocessor statement:  RESET_CONDITION(name) */   /* Preprocessor statement:  RESET_CONDITION(name) */
141    
142  <*>"RESET_CONDITION"[ \t]*"(" {  <*>"RESET_CONDITION"[ \t]*"(" {
143      printf("RESET_CONDITION\n");      //printf("RESET_CONDITION\n");
144      yy_push_state(PREPROC_RESET_COND, yyscanner);      yy_push_state(PREPROC_RESET_COND, yyscanner);
145  }  }
146  <PREPROC_RESET_COND>{ID} {  <PREPROC_RESET_COND>{ID} {
147      printf("preproc reset condition '%s'\n", yytext);      //printf("preproc reset condition '%s'\n", yytext);
148      bool success = yyextra->resetPreprocessorCondition(yytext);      bool success = yyextra->resetPreprocessorCondition(yytext);
149      if (!success) {      if (!success) {
150          SCANNER_ERR((String("Preprocessor: could not reset condition '") +          SCANNER_ERR((String("Preprocessor: could not reset condition '") +
# Line 133  ID       [a-zA-Z0-9_]* Line 152  ID       [a-zA-Z0-9_]*
152      }      }
153  }  }
154  <PREPROC_RESET_COND>[ \t]*")" {  <PREPROC_RESET_COND>[ \t]*")" {
155      printf("End of RESET_CONDITION\n");      //printf("End of RESET_CONDITION\n");
156      yy_pop_state(yyscanner);      yy_pop_state(yyscanner);
157  }  }
158    
# Line 152  ID       [a-zA-Z0-9_]* Line 171  ID       [a-zA-Z0-9_]*
171   */   */
172    
173  <*>"USE_CODE_IF"[ \t]*"(" {  <*>"USE_CODE_IF"[ \t]*"(" {
174      printf("USE_CODE_IF\n");      //printf("USE_CODE_IF\n");
175      yy_push_state(PREPROC_IF, yyscanner);      yy_push_state(PREPROC_IF, yyscanner);
176  }  }
177  <*>"USE_CODE_IF_NOT"[ \t]*"(" {  <*>"USE_CODE_IF_NOT"[ \t]*"(" {
178      printf("USE_CODE_IF_NOT\n");      //printf("USE_CODE_IF_NOT\n");
179      yy_push_state(PREPROC_IF_NOT, yyscanner);      yy_push_state(PREPROC_IF_NOT, yyscanner);
180  }  }
181  <PREPROC_IF>{ID} {  <PREPROC_IF>{ID} {
182      printf("preproc use code if '%s'\n", yytext);      //printf("preproc use code if '%s'\n", yytext);
183      yy_pop_state(yyscanner);      yy_pop_state(yyscanner);
184      if (yyextra->isPreprocessorConditionSet(yytext))      if (yyextra->isPreprocessorConditionSet(yytext))
185          yy_push_state(PREPROC_PRE_BODY_USE, yyscanner);          yy_push_state(PREPROC_PRE_BODY_USE, yyscanner);
# Line 168  ID       [a-zA-Z0-9_]* Line 187  ID       [a-zA-Z0-9_]*
187          yy_push_state(PREPROC_PRE_BODY_EAT, yyscanner);          yy_push_state(PREPROC_PRE_BODY_EAT, yyscanner);
188  }  }
189  <PREPROC_IF_NOT>{ID} {  <PREPROC_IF_NOT>{ID} {
190      printf("preproc use code if not '%s'\n", yytext);      //printf("preproc use code if not '%s'\n", yytext);
191      yy_pop_state(yyscanner);      yy_pop_state(yyscanner);
192      if (!yyextra->isPreprocessorConditionSet(yytext))      if (!yyextra->isPreprocessorConditionSet(yytext))
193          yy_push_state(PREPROC_PRE_BODY_USE, yyscanner);          yy_push_state(PREPROC_PRE_BODY_USE, yyscanner);
# Line 180  ID       [a-zA-Z0-9_]* Line 199  ID       [a-zA-Z0-9_]*
199      yy_push_state(PREPROC_BODY_USE, yyscanner);      yy_push_state(PREPROC_BODY_USE, yyscanner);
200  }  }
201  <PREPROC_PRE_BODY_EAT>[ \t]*")" {  <PREPROC_PRE_BODY_EAT>[ \t]*")" {
202        //printf("PREPROCESSOR EAT : \n");
203      yy_pop_state(yyscanner);      yy_pop_state(yyscanner);
204      yy_push_state(PREPROC_BODY_EAT, yyscanner);      yy_push_state(PREPROC_BODY_EAT, yyscanner);
205  }  }
206  <*>.*"END_USE_CODE" {  <*>.*"END_USE_CODE" {
207      printf("END_USE_CODE\n");      //printf("-->END_USE_CODE\n");
208      yy_pop_state(yyscanner);      yy_pop_state(yyscanner);
209  }  }
210    <PREPROC_BODY_EAT>[ \t\r\n]* { /* eat up code block filtered out by preprocessor */
211        processLocation();
212    }
213    <PREPROC_BODY_EAT>.* { /* eat up code block filtered out by preprocessor */
214        processLocation();
215    }
216    
217    
218   /* Language keywords */   /* Language keywords */
# Line 198  ID       [a-zA-Z0-9_]* Line 224  ID       [a-zA-Z0-9_]*
224  "declare" return DECLARE;  "declare" return DECLARE;
225  "while" return WHILE;  "while" return WHILE;
226  "if" return IF;  "if" return IF;
227    ".or." return BITWISE_OR;
228  "or" return OR;  "or" return OR;
229  "release" return RELEASE;  "release" return RELEASE;
230    ".and." return BITWISE_AND;
231  "and" return AND;  "and" return AND;
232    ".not." return BITWISE_NOT;
233  "not" return NOT;  "not" return NOT;
234  "else" return ELSE;  "else" return ELSE;
235  "controller" return CONTROLLER;  "controller" return CONTROLLER;
# Line 213  ID       [a-zA-Z0-9_]* Line 242  ID       [a-zA-Z0-9_]*
242  "polyphonic" return POLYPHONIC;  "polyphonic" return POLYPHONIC;
243  "mod" return MOD;  "mod" return MOD;
244    
245  on|end|note|init|declare|if|then|begin|end|procedure|function {  [&,()[\]<>=*+#/-] {
246      printf("A keyword: %s\n", yytext);      return *yytext;
247  }  }
248    
249  [&,()[\]<>=*+#/-] { return *yytext; }  ("$"|"@"|"%"){ID} {
   
 ("$"|"@"){ID} {  
     yylval->sValue = strdup(yytext);  
     return VARIABLE;  
 }  
   
 "%"{ID} {  
250      yylval->sValue = strdup(yytext);      yylval->sValue = strdup(yytext);
251      return VARIABLE;      return VARIABLE;
252  }  }
# Line 237  on|end|note|init|declare|if|then|begin|e Line 259  on|end|note|init|declare|if|then|begin|e
259  ":=" return ASSIGNMENT;  ":=" return ASSIGNMENT;
260    
261  \n+ {  \n+ {
262         yylineno += countNewLineChars(yytext);
263         yycolumn = 0;
264      //printf("lex: new line %d\n", yylineno, yytext);      //printf("lex: new line %d\n", yylineno, yytext);
265      //return LF;      //return LF;
266  }  }
267    
268  "{"[^}]*"}" /* eat up comments */  "{"[^}]*"}" { /* eat up comments */
269        processLocation();
270    }
271    
272  [ \t\r]+ /* eat up whitespace */  [ \t\r]+ /* eat up whitespace */
273    
274  "..." /* eat up */  . printf( "Unrecognized character: '%s' (line %d, column %d\n", yytext, yylineno, yycolumn);
   
 . printf( "Unrecognized character: %s\n", yytext );  
275    
276  %%  %%
277    

Legend:
Removed from v.2585  
changed lines
  Added in v.2935

  ViewVC Help
Powered by ViewVC