Example #1
0
PUBLIC EjsAny *ejsDeserialize(Ejs *ejs, EjsString *str)
{
    EjsObj      *obj;
    JsonState   js;

    if (!ejsIs(ejs, str, String)) {
        ejsThrowSyntaxError(ejs, "Object is not a string");
        return 0;
    }
    if (str->length == 0) {
        return ESV(empty);
    }
    js.next = js.data = str->value;
    js.end = &js.data[str->length];
    js.error = 0;
    if ((obj = parseLiteral(ejs, &js)) == 0) {
        if (js.error) {
            ejsThrowSyntaxError(ejs, 
                "Cannot parse object literal. Error at position %d.\n"
                "===========================\n"
                "Offending text: %w\n"
                "===========================\n"
                "In literal %w"
                "\n===========================\n",
                (int) (js.error - js.data), js.error, js.data);
        } else {
            ejsThrowSyntaxError(ejs, "Cannot parse object literal. Undefined error");
        }
        return 0;
    }
    return obj;
}
Example #2
0
void MacroEnsamZ::compilaExpresionOLiteral(Metodo::CuerpoMetodo &instrucc)
{
	lex->pasaEsp();

	// Quéviene ahora?
	Zero::AnalizadorLexico::TipoToken tk = lex->getTipoSiguienteToken();

	// Coger la expresié
	if (tk == Zero::AnalizadorLexico::IDENTIFICADOR)
	{
		lex->getToken();

		compilaExpresion(lex->getTokenActual(), mnemosMetActual, instrucc);
	}
	else
	if (tk != Zero::AnalizadorLexico::NADA) {
		Zero::Mnemotecnico * lit = parseLiteral();

		if (lit != NULL) {
			instrucc.push_back(lit);
		}
		else throw Zero::ESintaxis("se esperaba literal");
	}
	else throw Zero::ESintaxis("se esperaba expresión");
}
Example #3
0
PARSENODE_PTR SQLParser::parseExpression() {
    PARSENODE_PTR columnNode = parseIdentifier();
    PARSENODE_PTR opNode = parseOperator();
    PARSENODE_PTR valueNode = parseLiteral();
    opNode->children.push_back(columnNode);
    opNode->children.push_back(valueNode);
    return opNode;
}
Example #4
0
ast::Expr *parsePrimary(TokenIt &it, const TokenIt &end)
{
  Token *current = currentToken(it, end);
  EXPECT_ANY_TOKEN(current, errorE, "Expected a primary expression");
  
  switch(current->type)
  {
    case Token::IDENTIFIER: return parseIdentifier(it, end);
    case Token::NUMBER:     return parseLiteral(it, end);
    case Token::LPAREN:     return parseParenExpr(it, end);
    default:                return errorE("Unexpected token when expecting an expression");
  }
}
/**
 * Parses part of a regular expression string and builds a regular expression
 * tree with the given left subtree. The root node of the new tree is returned.
 * @param left The left subtree.
 * @param string The regular expression string.
 * @param pos The position of the parser in the regular expression.
 * @param len The length of the whole regular expression string.
 * @return The new root node of the expression tree.
 * @author Daniel Dreibrodt, Konstantin Steinmiller
 */
RETreeNode *REReaderWriter::parseNode(RETreeNode *left, const char string[], int *pos, int len) {
	if(*pos>=len) {
		//end of string reached, return last known tree root
		return left;
	}
    switch(string[*pos]) {
    	case '(' : {
    		throw "Read '(' but that is not allowed here!";
    		break;
    	}
    	case ')' : {
    		(*pos)++;
    		return left;
    		break;
    	}
    	case '|' : {
    		RETreeNode *opNode = new RETreeNode("|");
    		(*pos)++;
    		opNode->setLeft(left);
    		opNode->setRight(parseNode(string, pos, len));
    		return opNode;
    		break;
    	}
    	case '.' : {
    		RETreeNode *opNode = new RETreeNode(".");
			(*pos)++;
			opNode->setLeft(left);
			opNode->setRight(parseNode(string, pos, len));
			return opNode;
    		break;
    	}
    	case '*' : {
    		RETreeNode *opNode = new RETreeNode("*");
			(*pos)++;
			opNode->setLeft(left);

			return parseNode(opNode, string, pos, len);
    		break;
    	}
    	case ' ' : {
    		(*pos)++;
    		return parseNode(left, string, pos, len);
    		break;
    	}
    	default : {
    		RETreeNode *lit = parseLiteral(string,pos,len);
    		return parseNode(lit, string, pos, len);
    		break;
    	}
    }
}
Example #6
0
PARSENODE_PTR SQLParser::parseInsert() {
    if (!startsInsert(nowReading)) {
        syntaxError(nowReading, "expect insert token!");        
        return nullptr;
    }
    //LOG_TRACE(logger, "parse insert statement.");

    PARSENODE_PTR insertNode = PARSENODE_PTR(new ParseNode(INSERT));
    readToken();
    expect(INTO);
    insertNode->children.push_back(parseIdentifier());
    expect(VALUES);

    expect(LEFT_BRACE);
    insertNode->children.push_back(parseLiteral());
    while (nowReading == SLICE) {
        readToken();
        insertNode->children.push_back(parseLiteral());
    }
    expect(RIGHT_BRACE);

    expect(TERMINATOR);
    return insertNode;
}
/**
 * Parses a regular expression string and builds a regular expression
 * tree. The root node of that tree is returned.
 * @param string The regular expression string.
 * @param pos The position of the parser in the regular expression.
 * @param len The length of the whole regular expression string.
 * @return The root node of the expression tree.
 * @author Daniel Dreibrodt, Konstantin Steinmiller
 */
RETreeNode *REReaderWriter::parseNode(const char string[], int *pos, int len) {
	if(*pos>=len) {
		//end of string reached
		return NULL;
	}
    switch(string[*pos]) {
    	case '(' : {
    		(*pos)++;
    		RETreeNode *groupNode = parseNode(string, pos, len);
    		return parseNode(groupNode, string, pos, len);
    		break;
    	}
    	case ')' : {
    		throw "Read ')' but that is not allowed here!";
    		break;
    	}
    	case '|' : {
    		throw "Read '|' but that is not allowed here!";
    		break;
    	}
    	case '.' : {
    		throw "Read '.' but that is not allowed here!";
    		break;
    	}
    	case '*' : {
    		throw "Read '*' but that is not allowed here!";
    		break;
    	}
    	case ' ' : {
    		(*pos)++;
    		return parseNode(string, pos, len);
    		break;
    	}
    	default : {
    		RETreeNode *lit = parseLiteral(string,pos,len);
			return parseNode(lit, string, pos, len);
    		break;
    	}
    }
}
Example #8
0
/*
    Parse an object literal string pointed to by js->next into the given buffer. Update js->next to point
    to the next input token in the object literal. Supports nested object literals.
 */
static EjsObj *parseLiteralInner(Ejs *ejs, MprBuf *buf, JsonState *js)
{
    EjsAny      *obj, *vp;
    MprBuf      *valueBuf;
    wchar       *token, *key, *value;
    int         tid, isArray;

    isArray = 0;

    tid = getNextJsonToken(buf, &token, js);
    if (tid == TOK_ERR || tid == TOK_EOF) {
        return 0;
    }
    if (tid == TOK_LBRACKET) {
        isArray = 1;
        obj = (EjsObj*) ejsCreateArray(ejs, 0);
    } else if (tid == TOK_LBRACE) {
        obj = ejsCreateEmptyPot(ejs);
    } else {
        return ejsParse(ejs, token, S_String);
    }
    if (obj == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    while (1) {
        vp = 0;
        tid = peekNextJsonToken(js);
        if (tid == TOK_ERR) {
            return 0;
        } else if (tid == TOK_EOF) {
            break;
        } else if (tid == TOK_RBRACE || tid == TOK_RBRACKET) {
            getNextJsonToken(buf, &key, js);
            break;
        }
        if (tid == TOK_LBRACKET) {
            /* For array values */
            vp = parseLiteral(ejs, js);
            assert(vp);
            
        } else if (tid == TOK_LBRACE) {
            /* For object values */
            vp = parseLiteral(ejs, js);
            assert(vp);
            
        } else if (isArray) {
            tid = getNextJsonToken(buf, &value, js);
            vp = ejsParse(ejs, value, (tid == TOK_QID) ? S_String: -1);
            assert(vp);
            
        } else {
            getNextJsonToken(buf, &key, js);
            tid = peekNextJsonToken(js);
            if (tid == TOK_ERR) {
                return 0;
            } else if (tid == TOK_EOF) {
                break;
            } else if (tid == TOK_LBRACE || tid == TOK_LBRACKET) {
                vp = parseLiteral(ejs, js);

            } else if (tid == TOK_ID || tid == TOK_QID) {
                valueBuf = mprCreateBuf(0, 0);
                getNextJsonToken(valueBuf, &value, js);
                if (tid == TOK_QID) {
                    vp = ejsCreateString(ejs, value, strlen(value));
                } else {
                    if (mcmp(value, "null") == 0) {
                        vp = ESV(null);
                    } else if (mcmp(value, "undefined") == 0) {
                        vp = ESV(undefined);
                    } else {
                        vp = ejsParse(ejs, value, -1);
                    }
                }
                assert(vp);
            } else {
                getNextJsonToken(buf, &value, js);
                js->error = js->next;
                return 0;
            }
        }
        if (vp == 0) {
            js->error = js->next;
            return 0;
        }
        if (isArray) {
            if (ejsSetProperty(ejs, obj, -1, vp) < 0) {
                ejsThrowMemoryError(ejs);
                return 0;
            }
        } else {
            if (ejsSetPropertyByName(ejs, obj, WEN(key), vp) < 0) {
                ejsThrowMemoryError(ejs);
                return 0;
            }
        }
    }
    return obj;
}
Example #9
0
QList< Token > Engine::tokenize(QString ex)
{
	//presets
	Token::Type ctype=Token::Invalid;
	QString ctok;
	QList<Token> ret;
	int cline=1,ccol=0;
	int sline=cline,scol=ccol;
	int litend=-1;
	//go through expression
	for(int i=0;i<ex.size();i++){
		if(ex[i]=='\n'){cline++;ccol=0;}
		ccol++;
		//skip everything till end of a literal
		if(litend>i)continue;
		//get type of current character
		Token::Type ntype=d->cclass.charType(ex[i],ctype);
		//check for invalid stuff
		if(ntype==Token::Invalid)
			return QList<Token>()<<Token(Position(cline,ccol));
		//check whether we are still inside the same token
		if(ntype==ctype)
			ctok+=ex[i];
		else{
			//store old token
			if(ctype!=Token::Invalid && ctype!=Token::Whitespace && ctok!="")
				ret<<Token(ctok,ctype,Position(sline,scol));
			//reset state
			ctok.clear();
			sline=cline;
			scol=ccol;
			//handle current char
			switch(ntype){
				case Token::ParOpen:
				case Token::ParClose:
				case Token::Comma:
					//special chars
					ret<<Token(QString(ex[i]),ntype,Position(cline,ccol));
					ctype=Token::Invalid;
					break;
				case Token::Whitespace:
				case Token::Operator:
				case Token::Name:
					//start new token
					ctype=ntype;
					ctok+=ex[i];
					break;
				case Token::Literal:{
					//parse it
					QPair<QString,QVariant>lt=parseLiteral(ex,i);
					//check for failure
					if(lt.first=="")
						return QList<Token>()<<Token(Position(cline,ccol));
					//store token
					ret<<Token(lt.first,lt.second,Position(cline,ccol));
					//make the loop skip the rest
					litend=i+lt.first.size();
					ctype=Token::Invalid;
					break;}
				default://nothing
					qDebug()<<"oops. unexpected token type at line"<<cline<<"col"<<ccol;
					ctype=Token::Invalid;
					break;
			}
		}
	}
	//add remaining stuff
	if(ctype!=Token::Invalid && ctype!=Token::Whitespace && ctok!="")
		ret<<Token(ctok,ctype,Position(sline,scol));
	return ret;
}
Example #10
0
// -------------------------------------------- MacroEnsamZ::compilaExpresion()
void MacroEnsamZ::compilaExpresion(const std::string &tok,
                                   Metodo *& met,
				   Metodo::CuerpoMetodo &instrucc,
				   bool primerNivel)
/*
    compilar una expresion de este estilo:
    		expr ::= [<ref>]+.<metodo>(<expr>)

          System.console.write(x.concat("Mundo!"))
    A:
          STR "Mundo!"
          ASG __gp1
          MSG x concat __gp1
          MSG System.console write __acc
*/
{
	Zero::Mnemotecnico *mnemo;
	GestorNombresLoc nl;

	lex->pasaEsp();

	if ( Zero::NombreIdentificador::compruebaId( tok )
	 || ( Zero::NombreReferencia::compruebaRef( tok )
	   && lex->getCaracterActual() != '(' ) )
	{
		if ( !primerNivel )
		{
			// Es un identificador, se asigna al acc y punto
			mnemo = new(std::nothrow) Zero::NMSet( Zero::NombreRegistro::__ACC, tok );

			if ( mnemo != NULL )
				instrucc.push_back( mnemo );
			else throw Zero::ENoHayMemoria( "creando mnemo SET" );
		} else throw Zero::ESintxIdNoValido(
				"se esperaba asignacié o mensaje"
			);
	}
	else {
		if (Zero::NombreReferencia::compruebaRef( tok ) )
		{
                        // Es un mensaje a un objeto
			std::string refObjeto = tok;
			size_t posUltimoPunto = refObjeto.rfind( '.' );
			std::string nombreMetodo = refObjeto.substr( posUltimoPunto + 1 );

			// borra '*.met'
			refObjeto.erase(posUltimoPunto, refObjeto.size());
			lex->pasaEsp();
                        if( refObjeto.empty() ) {
                            refObjeto = ".";
                        }

			// Pasar el paréntesis, si existe
			if ( lex->getCaracterActual() == '(' ) {
				lex->avanza();
			}
			else throw Zero::ESintxIdNoValido("se esperaba apertura de parétesis '('");

			Zero::AnalizadorLexico::TipoToken tk = lex->getTipoSiguienteToken();
			do {
				// Compilar la sub-expresión
				if (tk == Zero::AnalizadorLexico::LITNUMERICO) {
					Zero::Mnemotecnico * lit = parseLiteral();

					if ( lit == NULL ) {
						throw Zero::ESintxIdNoValido(
							"se esperaba literal"
							"numérico" );
					}

					instrucc.insert(
						instrucc.begin(),
						new Zero::NMAsg( nl.crearNuevo(),
							   Zero::NombreRegistro::__ACC )
					);
					instrucc.insert( instrucc.begin(), lit );
				}
				else
				if (tk == Zero::AnalizadorLexico::LITCADENA) {
					Zero::Mnemotecnico * lit = parseLiteral();

					if (lit == NULL)
						throw Zero::ESintxIdNoValido("se esperaba literal cadena");

					// Guardar el mensaje
					instrucc.insert(instrucc.begin(),
						new Zero::NMAsg( nl.crearNuevo(),
							   Zero::NombreRegistro::__ACC )
					);
					instrucc.insert( instrucc.begin(), lit );
				}
				else
				if (tk == Zero::AnalizadorLexico::IDENTIFICADOR) {
					// Tomar el identificador
					lex->getToken();

					// Si es un identificador, adelante
					if ( Zero::NombreIdentificador::compruebaId(
						 lex->getTokenActual() )
				           )
					{
						if ( buscaVble(
						        objetoActual,
							metodoActual,
						        lex->getTokenActual() ) )
						{
							nl.insertarNuevo(
							  lex->getTokenActual()
							);
						} else {
							compilaExpresion(
								lex->getTokenActual(),
								met,
								instrucc
							);

							instrucc.push_back(
							     new Zero::NMAsg(
							       nl.crearNuevo(),
							       Zero::NombreRegistro::__ACC)
							);
						}
					}
					else {
						if ( Zero::NombreReferencia::compruebaRef(
						           lex->getTokenActual() ) )
						{
							// Es una referencia,
							// llamada recursiva
							compilaExpresion(
								lex->getTokenActual(),
								met,
								instrucc )
							;

							// Pasar el ')'
							if ( lex->getCaracterActual() == ')' ) {
								lex->avanza();
							}

							instrucc.push_back(
							     new Zero::NMAsg(
							       nl.crearNuevo(), Zero::NombreRegistro::__ACC)
							);
						}
						else throw Zero::ESintxIdNoValido("se esperaba un identificador"
						                     " o referencia");
					}
				}

				lex->pasaEsp();
				tk = lex->getTipoSiguienteToken();
			} while(( lex->getCaracterActual() != ')')
			    &&  ( !lex->esEol() ) );

			// Crear el mensaje
			Zero::NMMsg *msg = new Zero::NMMsg( refObjeto, nombreMetodo );

			// Argumentos
			while(!(nl.esVacio())) {
				msg->masArgumentos( nl.getSigNombre() );
			}

			instrucc.push_back( msg );
		}
		else throw Zero::ESintxIdNoValido("expresión debe empezar "
                                            "por referencia o identificador")
		           ;
	}
}