blob: 06b073d45b65f6968fd7bb0dabd812fffb31b7c9 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.mrql.gen;
import java_cup.runtime.Symbol;
final class Context {
public int[] parentheses;
public boolean[] match_begin;
public int current;
public Context () {
current = 0;
parentheses = new int[1000];
match_begin = new boolean[1000];
parentheses[0] = 0;
match_begin[0] = false;
}
public boolean no_parentheses () {
return parentheses[current] == 0;
}
public void new_context () {
parentheses[++current] = 0;
match_begin[current] = false;
}
public void close_context ( GenLex lex ) {
if (parentheses[current--] > 0)
lex.error("Unbalanced Parentheses in Gen construction/pattern");
if (current < 0)
lex.error("Wrong match statement");
}
public void open_parenthesis () {
parentheses[current]++;
}
public boolean close_parenthesis () {
return (--parentheses[current] == 0) && current > 0 && !match_begin[current];
}
public void in_match_body () {
match_begin[current] = true;
}
public boolean match_body () { return match_begin[current]; }
}
%%
%state gen
%class GenLex
%public
%line
%char
%cup
%eofval{
return new java_cup.runtime.Symbol(GenSym.EOF);
%eofval}
%{
public void error ( String msg ) {
throw new Error("*** Lexical Error: " + msg + " (line: " + line_pos() + ", position: " + char_pos() + ")");
}
public static Context context = new Context();
static int prev_char_pos = -1;
public int line_pos () { return yyline+1; }
public int char_pos () { return yychar-prev_char_pos; }
public Symbol symbol ( int s ) {
Tree.line_number = line_pos();
Tree.position_number = char_pos();
//System.out.println(context.parentheses[context.current]+" "+context.match_begin[context.current]+" "+GenParser.print(new Symbol(s)));
return new Symbol(s);
}
public Symbol symbol ( int s, Object o ) {
Tree.line_number = line_pos();
Tree.position_number = char_pos();
//System.out.println(context.parentheses[context.current]+" "+context.match_begin[context.current]+" "+GenParser.print(new Symbol(s,o)));
return new Symbol(s,o);
}
%}
DIGIT = [0-9]
ID = [a-zA-Z_][a-zA-Z0-9_]*
OPER = [!@#$%\^\&*-+=|\\~]+
NEWLINE = [\n\r]
DIGITS = {DIGIT}+
INT = ({DIGIT}|[1-9]{DIGITS}|-{DIGIT}|-[1-9]{DIGITS})
FRAC = [.]{DIGITS}
EXP = [eE][+-]?{DIGITS}
DOUBLE = ({INT}{FRAC}|{INT}{EXP}|{INT}{FRAC}{EXP})
%%
<gen> {INT} { return symbol(GenSym.LONG,new Long(yytext())); }
<gen> {DOUBLE} { return symbol(GenSym.DOUBLE,new Double(yytext())); }
<gen> ":" { yybegin(YYINITIAL);
context.close_context(this);
return symbol(GenSym.COLON); }
<gen> "_" { return symbol(GenSym.ANY); }
<gen> "," { return symbol(GenSym.COMMA); }
<gen> "`(" { context.new_context();
context.open_parenthesis();
yybegin(YYINITIAL);
return symbol(GenSym.BQP);
}
<gen> "...(" { context.new_context();
context.open_parenthesis();
yybegin(YYINITIAL);
return symbol(GenSym.DOTSP);
}
<gen> "`" { return symbol(GenSym.BQ); }
<gen> "..." { return symbol(GenSym.DOTS); }
<gen> "(" { context.open_parenthesis();
return symbol(GenSym.LP);
}
<gen> ")" { context.close_parenthesis();
return symbol(GenSym.RP);
}
<gen> "[" { context.open_parenthesis();
return symbol(GenSym.LB);
}
<gen> "]" { context.close_parenthesis();
if (context.no_parentheses())
{ yybegin(YYINITIAL);
context.close_context(this);
};
return symbol(GenSym.RB);
}
<gen> ">" { yybegin(YYINITIAL);
context.close_parenthesis();
context.close_context(this);
return symbol(GenSym.GT);
}
<gen> "is" { return symbol(GenSym.IS); }
<gen> {ID} { return symbol(GenSym.ID,yytext()); }
<gen> {OPER} { return symbol(GenSym.OPER,yytext()); }
<gen> \/\*[^*/]*\*\/ { for (char c: yytext().toCharArray())
if (c=='\n' || c=='\r')
GenParser.newlines++;
prev_char_pos = yychar; }
<gen> "//"[^\n\r]* { prev_char_pos = 0; }
<gen> [ \t\f] {}
<gen> {NEWLINE} { GenParser.newlines++; prev_char_pos = yychar; }
<gen> . { error("Illegal character in Gen construction/pattern: "+yytext()); }
<YYINITIAL> "match" { return symbol(GenSym.MATCH); }
<YYINITIAL> "case" { if (!context.match_body())
return symbol(GenSym.CHAR,yytext());
context.new_context();
yybegin(gen);
return symbol(GenSym.CASE);
}
<YYINITIAL> "fail" { return symbol(GenSym.FAIL); }
<YYINITIAL> "`" { error("Backquote outside a Gen construction/pattern"); }
<YYINITIAL> "#<" { context.new_context();
context.open_parenthesis();
yybegin(gen);
return symbol(GenSym.META);
}
<YYINITIAL> "#[" { context.new_context();
context.open_parenthesis();
yybegin(gen);
return symbol(GenSym.METAL);
}
<YYINITIAL> "{" { context.open_parenthesis();
if (context.match_body())
return symbol(GenSym.LSB);
else return symbol(GenSym.CHAR,yytext());
}
<YYINITIAL> "("|"[" { context.open_parenthesis();
return symbol(GenSym.CHAR,yytext());
}
<YYINITIAL> "}" { context.close_parenthesis();
if (context.match_body())
return symbol(GenSym.RSB);
else return symbol(GenSym.CHAR,yytext());
}
<YYINITIAL> ")" { if (context.close_parenthesis())
{ context.close_context(this);
yybegin(gen);
return symbol(GenSym.RP);
} else return symbol(GenSym.CHAR,yytext());
}
<YYINITIAL> "]" { if (context.close_parenthesis())
{ context.close_context(this);
yybegin(gen);
return symbol(GenSym.RB);
} else return symbol(GenSym.CHAR,yytext());
}
\"[^\"]*\" { return symbol(GenSym.CSTRING,yytext().substring(1,yytext().length()-1)); }
<YYINITIAL> {ID} { return symbol(GenSym.CHAR,yytext()); }
<YYINITIAL> {OPER} { return symbol(GenSym.CHAR,yytext()); }
<YYINITIAL> \/\*[^*/]*\*\/ { prev_char_pos = yychar; return symbol(GenSym.CHAR,yytext()); }
<YYINITIAL> "//"[^\n\r]* { prev_char_pos = 0; return symbol(GenSym.CHAR,yytext()); }
<YYINITIAL> [ \t\f] { return symbol(GenSym.CHAR,yytext()); }
<YYINITIAL> {NEWLINE} { prev_char_pos = yychar; return symbol(GenSym.CHAR,yytext()); }
<YYINITIAL> . { return symbol(GenSym.CHAR,yytext()); }