[Avida-SVN] r1780 - in development/source: script targets/avida-s

brysonda at myxo.css.msu.edu brysonda at myxo.css.msu.edu
Tue Jul 10 13:46:29 PDT 2007


Author: brysonda
Date: 2007-07-10 16:46:29 -0400 (Tue, 10 Jul 2007)
New Revision: 1780

Modified:
   development/source/script/AvidaScript.h
   development/source/script/cLexer.l
   development/source/script/cParser.cc
   development/source/script/cParser.h
   development/source/targets/avida-s/main.cc
Log:
Add basic call tracing (debugging purposes) to cParser.  Fix a few uncaught error conditions, though there are probably many to go.   Add more robust error reporting, including filename, line number, and actual token text.

Modified: development/source/script/AvidaScript.h
===================================================================
--- development/source/script/AvidaScript.h	2007-07-10 19:36:11 UTC (rev 1779)
+++ development/source/script/AvidaScript.h	2007-07-10 20:46:29 UTC (rev 1780)
@@ -30,46 +30,46 @@
   ENDL,
   COMMA,
   
-  OP_BIT_NOT,
+  OP_BIT_NOT, // 4
   OP_BIT_AND,
   OP_BIT_OR,
   
-  OP_LOGIC_NOT,
+  OP_LOGIC_NOT, // 7
   OP_LOGIC_AND,
   OP_LOGIC_OR,
   
-  OP_ADD,
+  OP_ADD, // 10
   OP_SUB,
   OP_MUL,
   OP_DIV,
   OP_MOD,
   
-  DOT,
+  DOT, // 15
   ASSIGN,
   REF,
   
-  OP_EQ,
+  OP_EQ, // 18
   OP_LE,
   OP_GE,
   OP_LT,
   OP_GT,
   OP_NEQ,
   
-  PREC_OPEN,
+  PREC_OPEN, // 24
   PREC_CLOSE,
   
-  IDX_OPEN,
+  IDX_OPEN, // 26
   IDX_CLOSE,
   
-  ARR_OPEN,
+  ARR_OPEN, // 28
   ARR_CLOSE,
   ARR_RANGE,
   ARR_EXPAN,
   ARR_WILD,
   
-  MAT_MODIFY,
+  MAT_MODIFY, // 33
   
-  TYPE_ARRAY,
+  TYPE_ARRAY, // 34
   TYPE_CHAR,
   TYPE_FLOAT,
   TYPE_INT,
@@ -77,29 +77,29 @@
   TYPE_STRING,
   TYPE_VOID,
   
-  CMD_IF,
+  CMD_IF, // 41
   CMD_ELSE,
   CMD_ENDIF,
   
-  CMD_WHILE,
+  CMD_WHILE, // 44
   CMD_ENDWHILE,
   
-  CMD_FOREACH,
+  CMD_FOREACH, // 46
   CMD_ENDFOREACH,
   
-  CMD_FUNCTION,
+  CMD_FUNCTION, // 48
   CMD_ENDFUNCTION,
   
-  CMD_RETURN,
+  CMD_RETURN, // 50
   
-  ID,
+  ID, // 51
   
-  FLOAT,
+  FLOAT, // 52
   INT,
   STRING,
   CHAR,
   
-  UNKNOWN,
+  UNKNOWN, // 56
   INVALID
 } ASToken_t;
 
@@ -108,6 +108,7 @@
   AS_PARSE_ERR_UNTERMINATED_EXPR,
   AS_PARSE_ERR_NULL_EXPR,
   AS_PARSE_ERR_EOF,
+  AS_PARSE_ERR_EMPTY,
   AS_PARSE_ERR_INTERNAL,
   AS_PARSE_ERR_UNKNOWN
 } ASParseError_t;

Modified: development/source/script/cLexer.l
===================================================================
--- development/source/script/cLexer.l	2007-07-10 19:36:11 UTC (rev 1779)
+++ development/source/script/cLexer.l	2007-07-10 20:46:29 UTC (rev 1780)
@@ -33,11 +33,12 @@
 
 %option c++
 %option noyywrap
+%option yylineno
 
 %%
 
 #.*\n       /* ignore comments */
-\/\/        /* ignore comments */
+\/\/.*\n    /* ignore comments */
 [ \t]+      /* ignore whitespace */
 
 

Modified: development/source/script/cParser.cc
===================================================================
--- development/source/script/cParser.cc	2007-07-10 19:36:11 UTC (rev 1779)
+++ development/source/script/cParser.cc	2007-07-10 20:46:29 UTC (rev 1780)
@@ -189,29 +189,49 @@
 
  */
 
+
+#define PARSE_DEBUG(x) { std::cerr << x << std::endl; }
+#define PARSE_TRACE(x) { std::cerr << "trace: " << x << std::endl; }
+
 #define PARSE_ERROR(x) reportError(AS_PARSE_ERR_ ## x, __LINE__)
 #define PARSE_UNEXPECT() { if (currentToken()) { PARSE_ERROR(UNEXPECTED_TOKEN); } else { PARSE_ERROR(EOF); } }
 
 
 cParser::cParser(cASLibrary* library)
 : m_library(library)
+, m_filename("(unknown)")
 , m_eof(false)
 , m_success(true)
 , m_cur_tok(INVALID)
 , m_next_tok(INVALID)
+, m_cur_text(NULL)
 , m_err_eof(false)
 {
 }
 
 bool cParser::Parse(cFile& input)
 {
+  m_filename = input.GetFilename();
   m_lexer = new cLexer(input.GetFileStream());
-  parseStatementList();
+  
+  m_tree = parseStatementList();
+
+  if (!m_eof) PARSE_UNEXPECT();
+  //if (!m_tree) PARSE_ERROR(EMPTY); @todo - statement list doesn't actually return anything yet
+
   delete m_lexer;
+  m_lexer = NULL;
   
   return m_success;
 }
 
+cParser::~cParser()
+{
+  delete m_tree;
+  delete m_lexer;
+}
+
+
 void cParser::Accept(cASTVisitor& visitor)
 {
   
@@ -225,12 +245,32 @@
   } else {
     m_cur_tok = (ASToken_t)m_lexer->yylex();
   }
+  delete m_cur_text;
+  m_cur_text = NULL;
+  PARSE_DEBUG("nextToken: " << m_cur_tok);
   return m_cur_tok;
 }
 
+ASToken_t cParser::peekToken()
+{
+  if (m_next_tok == INVALID) {
+    delete m_cur_text;
+    m_cur_text = new cString(m_lexer->YYText());
+    m_next_tok = (ASToken_t)m_lexer->yylex();
+  }
+  return m_next_tok;
+}
 
+const cString& cParser::currentText()
+{
+  if (!m_cur_text) m_cur_text = new cString(m_lexer->YYText());
+  return *m_cur_text;
+}
+
+
 cASTNode* cParser::parseArrayUnpack()
 {
+  PARSE_TRACE("parseArrayUnpack");
   cASTNode* au = NULL;
   
   if (nextToken() != ID) {
@@ -262,6 +302,7 @@
 
 cASTNode* cParser::parseArgumentList()
 {
+  PARSE_TRACE("parseArgumentList");
   cASTNode* al = NULL;
   
   parseExpression();
@@ -274,6 +315,7 @@
 
 cASTNode* cParser::parseAssignment()
 {
+  PARSE_TRACE("parseAssignment");
   cASTNode* an = NULL;
   
   nextToken();
@@ -284,6 +326,7 @@
 
 cASTNode* cParser::parseCallExpression()
 {
+  PARSE_TRACE("parseCallExpression");
   cASTNode* ce = NULL;
   
   bool eoe = false;
@@ -296,9 +339,8 @@
         }
         break;
       case PREC_OPEN:
-        nextToken();
-        parseArgumentList();
-        if (nextToken() != PREC_CLOSE) {
+        if (nextToken() != PREC_CLOSE) parseArgumentList();
+        if (currentToken() != PREC_CLOSE) {
           PARSE_UNEXPECT();
           return ce;   
         }
@@ -331,6 +373,7 @@
 
 cASTNode* cParser::parseCodeBlock(bool& loose)
 {
+  PARSE_TRACE("parseCodeBlock");
   cASTNode* cb = NULL;
 
   nextToken();
@@ -349,6 +392,7 @@
 
 cASTNode* cParser::parseExpression()
 {
+  PARSE_TRACE("parseExpression");
   cASTNode* expr = NULL;
   
   expr = parseExprP0();
@@ -364,6 +408,7 @@
 
 cASTNode* cParser::parseExprP0()
 {
+  PARSE_TRACE("parseExprP0");
   cASTNode* l = parseExprP1();
   cASTNode* r = NULL;
   
@@ -374,6 +419,7 @@
         ASToken_t op = currentToken();
         nextToken();
         r = parseExprP1();
+        if (!r) PARSE_ERROR(NULL_EXPR);
         l = new cASTExpressionBinary(op, l, r);
         break;
         
@@ -387,6 +433,7 @@
 
 cASTNode* cParser::parseExprP1()
 {
+  PARSE_TRACE("parseExprP1");
   cASTNode* l = parseExprP2();
   cASTNode* r = NULL;
   
@@ -397,6 +444,7 @@
         ASToken_t op = currentToken();
         nextToken();
         r = parseExprP2();
+        if (!r) PARSE_ERROR(NULL_EXPR);
         l = new cASTExpressionBinary(op, l, r);
         break;
         
@@ -410,6 +458,7 @@
 
 cASTNode* cParser::parseExprP2()
 {
+  PARSE_TRACE("parseExprP2");
   cASTNode* l = parseExprP3();
   cASTNode* r = NULL;
   
@@ -420,6 +469,7 @@
         ASToken_t op = currentToken();
         nextToken();
         r = parseExprP3();
+        if (!r) PARSE_ERROR(NULL_EXPR);
         l = new cASTExpressionBinary(op, l, r);
         break;
         
@@ -433,6 +483,7 @@
 
 cASTNode* cParser::parseExprP3()
 {
+  PARSE_TRACE("parseExprP3");
   cASTNode* l = parseExprP4();
   cASTNode* r = NULL;
   
@@ -447,6 +498,7 @@
         ASToken_t op = currentToken();
         nextToken();
         r = parseExprP4();
+        if (!r) PARSE_ERROR(NULL_EXPR);
         l = new cASTExpressionBinary(op, l, r);
         break;
         
@@ -460,6 +512,7 @@
 
 cASTNode* cParser::parseExprP4()
 {
+  PARSE_TRACE("parseExprP4");
   cASTNode* l = parseExprP5();
   cASTNode* r = NULL;
   
@@ -470,6 +523,7 @@
         ASToken_t op = currentToken();
         nextToken();
         r = parseExprP5();
+        if (!r) PARSE_ERROR(NULL_EXPR);
         l = new cASTExpressionBinary(op, l, r);
         break;
         
@@ -483,6 +537,7 @@
 
 cASTNode* cParser::parseExprP5()
 {
+  PARSE_TRACE("parseExprP5");
   cASTNode* l = parseExprP6();
   cASTNode* r = NULL;
   
@@ -494,6 +549,7 @@
         ASToken_t op = currentToken();
         nextToken();
         r = parseExprP6();
+        if (!r) PARSE_ERROR(NULL_EXPR);
         l = new cASTExpressionBinary(op, l, r);
         break;
         
@@ -507,6 +563,7 @@
 
 cASTNode* cParser::parseExprP6()
 {
+  PARSE_TRACE("parseExprP6");
   cASTNode* expr = NULL;
   
   switch (currentToken()) {
@@ -519,8 +576,7 @@
     case ID:
       if (peekToken() == PREC_OPEN) {
         nextToken();
-        nextToken();
-        parseArgumentList();
+        if (nextToken() != PREC_CLOSE) parseArgumentList();
         if (currentToken() != PREC_CLOSE) {
           PARSE_UNEXPECT();
           return expr;
@@ -533,6 +589,7 @@
     case PREC_OPEN:
       nextToken();
       expr = parseExpression();
+      if (!expr) PARSE_ERROR(NULL_EXPR);
       if (currentToken() != PREC_CLOSE) {
         PARSE_UNEXPECT();
         return expr;
@@ -544,8 +601,7 @@
         return expr;
       }
     case ARR_OPEN:
-      nextToken();
-      parseArgumentList();
+      if (nextToken() != ARR_CLOSE) parseArgumentList();
       if (currentToken() != ARR_CLOSE) {
         PARSE_UNEXPECT();
         return expr;
@@ -557,6 +613,7 @@
     case OP_SUB:
       ASToken_t op = currentToken();
       expr = new cASTExpressionUnary(op, parseExpression());
+      if (!expr) PARSE_ERROR(NULL_EXPR);
       nextToken();
       return expr;
       
@@ -564,12 +621,14 @@
       break;
   }
 
+  nextToken();
   if (expr) expr = parseExprP6_Index(expr);
   return expr;
 }
 
 cASTNode* cParser::parseExprP6_Index(cASTNode* l)
 {
+  PARSE_TRACE("parseExprP6_Index");
   while (currentToken() == DOT || currentToken() == IDX_OPEN) {
     if (currentToken() == DOT) {
       if (nextToken() != ID) {
@@ -578,8 +637,7 @@
       }
       if (peekToken() == PREC_OPEN) {
         nextToken();
-        nextToken();
-        parseArgumentList();
+        if (nextToken() != PREC_CLOSE) parseArgumentList();
         if (currentToken() != PREC_CLOSE) {
           PARSE_UNEXPECT();
           return l;
@@ -605,6 +663,7 @@
 
 cASTNode* cParser::parseForeachStatement()
 {
+  PARSE_TRACE("parseForeachStatement");
   cASTNode* fs = NULL;
   
   switch (nextToken()) {
@@ -649,6 +708,7 @@
 
 cASTNode* cParser::parseFunctionDefine()
 {
+  PARSE_TRACE("parseFunctionDefine");
   cASTNode* fd = parseFunctionHeader(false);
   
   bool loose = false;
@@ -663,6 +723,7 @@
 
 cASTNode* cParser::parseFunctionHeader(bool declare)
 {
+  PARSE_TRACE("parseFunctionHeader");
   cASTNode* fd = NULL;
   
   switch (nextToken()) {
@@ -697,14 +758,15 @@
     return fd;
   }
   
-  nextToken();
-  if (declare) {
-    parseVarDeclareList();
-  } else {
-    parseArgumentList();
+  if (nextToken() != PREC_CLOSE) {
+    if (declare) {
+      parseVarDeclareList();
+    } else {
+      parseArgumentList();
+    }
   }
   
-  if (nextToken() != PREC_CLOSE) {
+  if (currentToken() != PREC_CLOSE) {
     PARSE_UNEXPECT();
     return fd;    
   }
@@ -714,6 +776,7 @@
 
 cASTNode* cParser::parseIDStatement()
 {
+  PARSE_TRACE("parseIDStatement");
   cASTNode* is = NULL;
   
   switch (nextToken()) {
@@ -739,6 +802,7 @@
 
 cASTNode* cParser::parseIfStatement()
 {
+  PARSE_TRACE("parseIfStatement");
   cASTNode* is = NULL;
   
   if (nextToken() != PREC_OPEN) {
@@ -772,6 +836,7 @@
 
 cASTNode* cParser::parseIndexExpression()
 {
+  PARSE_TRACE("parseIndexExpression");
   cASTNode* ie = NULL;
   
   nextToken();
@@ -785,6 +850,7 @@
 
 cASTNode* cParser::parseLooseBlock()
 {
+  PARSE_TRACE("parseLooseBlock");
   nextToken();
   cASTNode* sl = parseStatementList();
   if (currentToken() != ARR_CLOSE) {
@@ -795,6 +861,7 @@
 
 cASTNode* cParser::parseRefStatement()
 {
+  PARSE_TRACE("parseRefStatement");
   cASTNode* rs = NULL;
 
   switch (nextToken()) {
@@ -813,6 +880,7 @@
 
 cASTNode* cParser::parseReturnStatement()
 {
+  PARSE_TRACE("parseReturnStatement");
   cASTNode* rs = NULL;
   
   nextToken();
@@ -823,6 +891,7 @@
 
 cASTNode* cParser::parseStatementList()
 {
+  PARSE_TRACE("parseStatementList");
   cASTNode* sl = NULL;
 
 #define CHECK_LINETERM() { if (!checkLineTerm(sl)) return sl; }
@@ -886,6 +955,7 @@
 
 cASTNode* cParser::parseVarDeclare()
 {
+  PARSE_TRACE("parseVarDeclare");
   cASTNode* vd = NULL;
   
   switch (currentToken()) {
@@ -919,8 +989,7 @@
       parseExpression();
       break;
     case PREC_OPEN:
-      nextToken();
-      parseArgumentList();
+      if (nextToken() != PREC_CLOSE) parseArgumentList();
       if (currentToken() != PREC_CLOSE) {
         PARSE_UNEXPECT();
         return vd;
@@ -936,6 +1005,7 @@
 
 cASTNode* cParser::parseVarDeclareList()
 {
+  PARSE_TRACE("parseVarDeclareList");
   cASTNode* vl = NULL;
   
   parseVarDeclare();
@@ -948,7 +1018,8 @@
 
 cASTNode* cParser::parseWhileStatement()
 {
-  cASTNode* ws = NULL;
+  PARSE_TRACE("parseWhileStatement");
+ cASTNode* ws = NULL;
   
   if (nextToken() != PREC_OPEN) {
     PARSE_UNEXPECT();
@@ -976,7 +1047,7 @@
 
 bool cParser::checkLineTerm(cASTNode* node)
 {
-  nextToken();
+  PARSE_TRACE("checkLineTerm");
   if (currentToken() == SUPPRESS) {
     // @todo - mark output as suppressed
     return true;
@@ -993,23 +1064,32 @@
 {
   m_success = false;
 
-  std::cerr << "error: ";
+  std::cerr << m_filename << ":";
+  
+  int lineno = m_lexer ? m_lexer->lineno() : 0;
+  if (lineno) std::cerr << lineno;
+  else std::cerr << "?";
+  
+  std::cerr << ": error: ";
 
   switch (err) {
     case AS_PARSE_ERR_UNEXPECTED_TOKEN:
-      std::cerr << "unexpected token '" << currentToken() << "'." << std::endl;
+      std::cerr << "unexpected token '" << currentText() << "'." << std::endl;
       break;
     case AS_PARSE_ERR_UNTERMINATED_EXPR:
-      std::cerr << "unterminated expression'" << currentToken() << "'." << std::endl;
+      std::cerr << "unterminated expression." << std::endl;
       break;
     case AS_PARSE_ERR_NULL_EXPR:
-      std::cerr << "expected expression, found '" << currentToken() << "'." << std::endl;
+      std::cerr << "expected expression, found '" << currentText() << "'." << std::endl;
     case AS_PARSE_ERR_EOF:
       if (!m_err_eof) {
         std::cerr << "unexpected end of file" << std::endl;
         m_err_eof = true;
       }
       break;
+    case AS_PARSE_ERR_EMPTY:
+      std::cerr << "empty script, no valid statements found" << std::endl;
+      break;
     case AS_PARSE_ERR_INTERNAL:
       std::cerr << "internal parser error at cParser.cc:" << line << std::endl;
     case AS_PARSE_ERR_UNKNOWN:

Modified: development/source/script/cParser.h
===================================================================
--- development/source/script/cParser.h	2007-07-10 19:36:11 UTC (rev 1779)
+++ development/source/script/cParser.h	2007-07-10 20:46:29 UTC (rev 1780)
@@ -53,6 +53,9 @@
 {
 private:
   cASLibrary* m_library;
+  
+  cString m_filename;
+  
   cLexer* m_lexer;
   cASTNode* m_tree;
 
@@ -61,6 +64,7 @@
   
   ASToken_t m_cur_tok;
   ASToken_t m_next_tok;
+  cString* m_cur_text;
   
   bool m_err_eof;
   
@@ -72,6 +76,7 @@
   
 public:
   cParser(cASLibrary* library);
+  ~cParser();
   
   bool Parse(cFile& input);
   void Accept(cASTVisitor& visitor);
@@ -80,8 +85,10 @@
 private:
   inline ASToken_t currentToken() { return m_cur_tok; }
   ASToken_t nextToken();
-  inline ASToken_t peekToken();
+  ASToken_t peekToken();
   
+  const cString& currentText();
+  
   cASTNode* parseArgumentList();
   cASTNode* parseArrayUnpack();
   cASTNode* parseAssignment();
@@ -116,11 +123,4 @@
 };
 
 
-inline ASToken_t cParser::peekToken()
-{
-  if (m_next_tok == INVALID) m_next_tok = (ASToken_t)m_lexer->yylex();
-  return m_next_tok;
-}
-
-
 #endif

Modified: development/source/targets/avida-s/main.cc
===================================================================
--- development/source/targets/avida-s/main.cc	2007-07-10 19:36:11 UTC (rev 1779)
+++ development/source/targets/avida-s/main.cc	2007-07-10 20:46:29 UTC (rev 1780)
@@ -28,7 +28,9 @@
 #include "cParser.h"
 #include "PlatformExpert.h"
 
+#include <iostream>
 
+
 int main (int argc, char * const argv[])
 {
   PlatformExpert::Initialize();
@@ -37,9 +39,17 @@
   cParser* parser = new cParser(lib);
   
   cFile file;
-  if (file.Open("main.asl")) parser->Parse(file);
+  if (file.Open("main.asl")) {
+    if (parser->Parse(file)) {
+      std::cout << "Parse Successful" << std::endl;
+      ExitAvida(0);
+    } else {
+      std::cout << "Parse Failed" << std::endl;
+      ExitAvida(1);
+    }
+  } else {
+    std::cerr << "error: unable to open script" << std::endl;
+  }
   
-  ExitAvida(0);
-  
-  return 0;
+  return -1;
 }




More information about the Avida-cvs mailing list