summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/camp.l
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/asymptote/camp.l')
-rw-r--r--Build/source/utils/asymptote/camp.l406
1 files changed, 406 insertions, 0 deletions
diff --git a/Build/source/utils/asymptote/camp.l b/Build/source/utils/asymptote/camp.l
new file mode 100644
index 00000000000..f6b53c40f85
--- /dev/null
+++ b/Build/source/utils/asymptote/camp.l
@@ -0,0 +1,406 @@
+%{
+/*****
+ * camp.l
+ * Andy Hammerlindl 2002/06/14
+ *
+ * The lexical analyzer of the Asymptote language.
+ *****/
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+#include "util.h"
+#include "modifier.h"
+#include "exp.h"
+#include "stm.h"
+#include "fundec.h"
+#include "errormsg.h"
+#include "interact.h"
+#include "lexical.h"
+
+using namespace absyntax;
+using mem::string;
+
+#include "camp.tab.h"
+
+#define YY_NO_UNPUT
+
+fileinfo* fi;
+Int tokPos;
+Int charPos;
+//int commentDepth = 0;
+
+bool eof;
+string eofMessage;
+
+extern errorstream em;
+
+extern "C" int yywrap(void)
+{
+ charPos=1;
+ return 1;
+}
+
+typedef size_t (*input_f) (char* bif, size_t max_size);
+
+input_f yy_input = NULL;
+
+void setlexer(input_f input, string filename)
+{
+ YY_FLUSH_BUFFER;
+ yywrap();
+ fi = new fileinfo(filename);
+ yy_input = input;
+ tokPos = charPos = 1;
+
+ eof=false;
+ eofMessage="<no eof>";
+}
+
+#define YY_INPUT(buf,result,max_size) {result=yy_input(buf,max_size);}
+
+position lexerPos()
+{
+ position p;
+ p.init(fi, tokPos);
+ return p;
+}
+
+namespace {
+position here()
+
+{
+ return lexerPos();
+}
+
+void adjust()
+{
+ tokPos = charPos;
+ charPos += yyleng;
+ yylval.pos = here();
+}
+
+void makesymbol(bool op=true, string text = yytext)
+{
+ adjust();
+ yylval.ps.pos=here();
+ yylval.ps.sym=op ? symbol::opTrans(text) : symbol::literalTrans(text);
+}
+
+void makeselfsymbol(bool op=true, string text = yytext)
+{
+ /* Copy all but the last digit, which should be an =. */
+ assert(text[text.length()-1] == '=');
+ text.erase(text.length()-1);
+ makesymbol(op,text);
+}
+
+void makemod(trans::modifier mod) {
+ yylval.mod.pos=here();
+ yylval.mod.val=mod;
+}
+
+void makeperm(trans::permission perm) {
+ yylval.perm.pos=here();
+ yylval.perm.val=perm;
+}
+
+void newline()
+{
+ fi->newline();
+ charPos = tokPos = 1;
+}
+
+void error(void)
+{
+ em.error(here());
+}
+
+}
+
+
+// Used by the lexer rules to flag an unexpected end of input. The message is
+// the error message that should be reported, and may differ if, say the input
+// ends in the middle of a string or comment.
+void setEOF(string message) {
+ eof=true;
+ eofMessage=message;
+}
+
+// Called by code outside of the lexer to see if a parse error was caused by
+// running out of input.
+bool lexerEOF()
+{
+ return eof;
+}
+
+// Called by code outside of the lexer when it wants to report the unexpected
+// eof as an error (instead of looking for more input).
+void reportEOF() {
+ assert(eof);
+ error();
+ em << eofMessage;
+ em.sync();
+}
+
+string stringbuild;
+
+namespace {
+void append(char c)
+{
+ stringbuild.push_back(c);
+ yylval.pos = here();
+}
+
+void getstring(void)
+{
+ // NOTE: Replace here() with a position at the start of the string.
+ makesymbol(false,stringbuild);
+ string().swap(stringbuild);
+}
+}
+
+%}
+
+%x lexcomment
+%x texstring
+%x cstring
+%x lexformat
+%x opname
+
+LETTER [_A-Za-z]
+ESC \\
+ENDL \\?(\r\n|\n|\r)
+EXTRAOPS <<|>>|$|$$|@|@@|~
+
+%%
+
+<lexcomment>{
+\/\* {adjust(); /*commentDepth++;*/}
+\*\/ {adjust(); /*commentDepth--;*/
+ /*if (commentDepth == 0)*/ BEGIN INITIAL; }
+\r\n|\n|\r {adjust(); newline(); continue; }
+<<EOF>> {adjust();
+ setEOF("comment not terminated");
+ BEGIN INITIAL;
+ return GARBAGE;
+ }
+. {adjust(); continue; }
+}
+
+<texstring>{
+\"/([ \t]|{ENDL})*[\"\'] {adjust(); BEGIN INITIAL;}
+\" {adjust();
+ BEGIN INITIAL;
+ getstring();
+ return STRING; }
+<<EOF>> {adjust();
+ setEOF("string not terminated");
+ BEGIN INITIAL;
+ getstring();
+ return GARBAGE;
+ }
+{ENDL} {adjust(); newline(); append('\n'); continue; }
+{ESC}{ESC} {adjust(); append('\\'); append('\\'); continue; }
+{ESC}\" {adjust(); append('\"'); continue; }
+. {adjust(); append(*yytext); }
+}
+
+<cstring>{
+\'/([ \t]|{ENDL})*[\"\'] {adjust(); BEGIN INITIAL;}
+\' {adjust();
+ BEGIN INITIAL;
+ getstring();
+ return STRING; }
+<<EOF>> {adjust();
+ setEOF("string not terminated");
+ BEGIN INITIAL;
+ getstring();
+ return GARBAGE;
+ }
+{ENDL} {adjust(); newline(); append('\n'); continue; }
+{ESC}(\'|\"|\?|\\) {adjust(); append(yytext[1]); continue; }
+{ESC}a {adjust(); append('\a'); continue; }
+{ESC}b {adjust(); append('\b'); continue; }
+{ESC}f {adjust(); append('\f'); continue; }
+{ESC}n {adjust(); append('\n'); continue; }
+{ESC}r {adjust(); append('\r'); continue; }
+{ESC}t {adjust(); append('\t'); continue; }
+{ESC}v {adjust(); append('\v'); continue; }
+{ESC}[0-7] {adjust();
+ char x=(char)(yytext[1]-'0');
+ append(x);
+ continue;
+ }
+{ESC}[0-7][0-7] {adjust();
+ char x=(char)((yytext[1]-'0')*8+yytext[2]-'0');
+ append(x);
+ continue;
+ }
+{ESC}[0-3][0-7][0-7] {adjust();
+ char x=(char)((yytext[1]-'0')*64+(yytext[2]-'0')*8
+ +yytext[3]-'0');
+ append(x);
+ continue;
+ }
+{ESC}x[0-9,A-F] {adjust();
+ char x=(char) (yytext[2] <= '9' ? yytext[2]-'0' :
+ 10+yytext[2]-'A');
+ append(x);
+ continue;
+ }
+{ESC}x[0-9,A-F][0-9,A-F] {adjust();
+ char x=(char) ((yytext[2] <= '9' ? yytext[2]-'0' :
+ 10+yytext[2]-'A')*16
+ +(yytext[3] <= '9' ? yytext[3]-'0' :
+ 10+yytext[3]-'A'));
+ append(x);
+ continue;
+ }
+. {adjust(); append(*yytext); }
+}
+
+[ \t] {adjust(); continue;}
+{ENDL} {adjust(); newline(); continue;}
+\/\/[^\n]* {adjust(); continue;}
+"," {adjust(); return ','; }
+":" {adjust(); return ':'; }
+";" {adjust(); return ';'; }
+"(" {adjust(); return '('; }
+")" {adjust(); return ')'; }
+"[" {adjust(); return '['; }
+"]" {adjust(); return ']'; }
+"{" {adjust(); return '{'; }
+"}" {adjust(); return '}'; }
+"." {adjust(); return '.'; }
+"..." {adjust(); return ELLIPSIS; }
+"+" {makesymbol(); return '+'; }
+"-" {makesymbol(); return '-'; }
+"*" {makesymbol(); return '*'; }
+"/" {makesymbol(); return '/'; }
+"%" {makesymbol(); return '%'; }
+"^" {makesymbol(); return '^'; }
+"**" {makesymbol(true,"^"); return '^'; }
+"?" {adjust(); return '?'; }
+"=" {adjust(); return ASSIGN; }
+"==" {makesymbol(); return EQ; }
+"!=" {makesymbol(); return NEQ; }
+"<" {makesymbol(); return LT; }
+"<=" {makesymbol(); return LE; }
+">" {makesymbol(); return GT; }
+">=" {makesymbol(); return GE; }
+"&&" {makesymbol(); return CAND; }
+"||" {makesymbol(); return COR; }
+"!" {makesymbol(); return LOGNOT; }
+"^^" {makesymbol(); return CARETS; }
+"::" {makesymbol(); return COLONS; }
+"++" {makesymbol(); return INCR; }
+".." {makesymbol(); return DOTS; }
+"--" {makesymbol(); return DASHES; }
+"---" {makesymbol(); return LONGDASH; }
+"&" {makesymbol(); return AMPERSAND; }
+"|" {makesymbol(); return BAR; }
+{EXTRAOPS} {makesymbol(); return OPERATOR; }
+
+"+=" {makeselfsymbol(); return ADD; }
+"-=" {makeselfsymbol(); return SUBTRACT; }
+"*=" {makeselfsymbol(); return TIMES; }
+"/=" {makeselfsymbol(); return DIVIDE; }
+"%=" {makeselfsymbol(); return MOD; }
+"^=" {makeselfsymbol(); return EXPONENT; }
+
+and {adjust(); return AND; }
+controls {makesymbol(); return CONTROLS; }
+tension {makesymbol(); return TENSION; }
+atleast {makesymbol(); return ATLEAST; }
+curl {makesymbol(); return CURL; }
+
+if {adjust(); return IF; }
+else {adjust(); return ELSE; }
+while {adjust(); return WHILE; }
+for {adjust(); return FOR; }
+do {adjust(); return DO; }
+return {adjust(); return RETURN_; }
+break {adjust(); return BREAK; }
+continue {adjust(); return CONTINUE; }
+struct {adjust(); return STRUCT; }
+typedef {adjust(); return TYPEDEF; }
+new {adjust(); return NEW; }
+access {adjust(); return ACCESS; }
+import {adjust(); return IMPORT; }
+unravel {adjust(); return UNRAVEL; }
+from {adjust(); return FROM; }
+include {adjust(); return INCLUDE; }
+quote {adjust(); return QUOTE; }
+static {adjust(); makemod(trans::EXPLICIT_STATIC);
+ return MODIFIER; }
+public {adjust(); makeperm(trans::PUBLIC); return PERM; }
+private {adjust(); makeperm(trans::PRIVATE); return PERM; }
+restricted {adjust(); makeperm(trans::RESTRICTED); return PERM; }
+this {adjust(); return THIS; }
+explicit {adjust(); return EXPLICIT; }
+
+
+[0-9]+ try {
+ adjust(); yylval.e= new intExp(here(), lexical::cast<Int>(yytext));
+ } catch (lexical::bad_cast&) {
+ error();
+ em << "invalid integer";
+ yylval.e= new intExp(here(), 0);
+ } return LIT;
+([0-9]*\.[0-9]+)|([0-9]+\.[0-9]*)|([0-9]*\.*[0-9]+e[-+]*[0-9]+)|([0-9]+\.[0-9]*e[-+]*[0-9]+) try {
+ adjust(); yylval.e= new realExp(here(), lexical::cast<double>(yytext));
+ } catch (lexical::bad_cast&) {
+ error();
+ em << "invalid real";
+ yylval.e= new realExp(here(), 0);
+ } return LIT;
+true {
+ adjust(); yylval.e= new booleanExp(here(), true); return LIT; }
+false {
+ adjust(); yylval.e= new booleanExp(here(), false); return LIT; }
+null {
+ adjust(); yylval.e= new nullExp(here()); return LIT; }
+cycle {
+ adjust(); yylval.e= new cycleExp(here()); return LIT; }
+newframe {
+ adjust(); yylval.e= new newPictureExp(here()); return LIT; }
+
+operator {adjust(); BEGIN opname; }
+<opname>{
+[ \t\r] {adjust(); continue;}
+{ENDL} {adjust(); newline(); continue;}
+<<EOF>> {adjust();
+ setEOF("missing operator name");
+ BEGIN INITIAL;
+ return GARBAGE;
+ }
+"**" { makesymbol(true, "^");
+ BEGIN INITIAL;
+ return ID;
+ }
+[-+*/%^!<>]|==|!=|<=|>=|&|\||\^\^|\.\.|::|--|---|\+\+|{EXTRAOPS} {
+ makesymbol();
+ BEGIN INITIAL;
+ return ID;}
+{LETTER}({LETTER}|[0-9])* {
+ makesymbol(true);
+ BEGIN INITIAL;
+ return ID; }
+. {}
+}
+
+{LETTER}({LETTER}|[0-9])* {
+ makesymbol(false);
+ return ID; }
+
+\/\* {adjust(); /*commentDepth = 1;*/ BEGIN lexcomment; }
+\" {adjust(); BEGIN texstring; }
+\' {adjust(); BEGIN cstring; }
+
+<<EOF>> { setEOF("unexpected end of input"); yyterminate(); }
+
+. {
+ adjust(); error(); em <<"invalid token '" << yytext << "'"; }
+