Exemple #1
0
/**

We here treat the property values as expressions:

	padding: {expression} {expression} {expression};
	margin: {expression};

*/
func (parser *Parser) ParseExpr(inParenthesis bool) ast.Expr {
	var pos = parser.Pos

	// plus or minus. This creates an unary expression that holds the later term.
	// this is for:  +3 or -4
	var expr ast.Expr = nil

	if tok := parser.acceptAnyOf2(ast.T_PLUS, ast.T_MINUS); tok != nil {
		if term := parser.ParseTerm(); term != nil {
			expr = ast.NewUnaryExpr(ast.NewOpWithToken(tok), term)

			if uexpr, ok := expr.(*ast.UnaryExpr); ok {

				// if it's evaluatable just return the evaluated value.
				if val, ok := runtime.ReduceExpr(uexpr, parser.GlobalContext); ok {
					expr = ast.Expr(val)
				}
			}
		} else {
			parser.restore(pos)
			return nil
		}
	} else {
		expr = parser.ParseTerm()
	}

	if expr == nil {
		debug("ParseExpr failed, got %+v, restoring to %d", expr, pos)
		parser.restore(pos)
		return nil
	}

	var rightTok = parser.peek()
	for rightTok.Type == ast.T_PLUS || rightTok.Type == ast.T_MINUS || rightTok.Type == ast.T_LITERAL_CONCAT {
		// accept plus or minus
		parser.advance()

		if rightTerm := parser.ParseTerm(); rightTerm != nil {
			// XXX: check parenthesis
			var bexpr = ast.NewBinaryExpr(ast.NewOpWithToken(rightTok), expr, rightTerm, inParenthesis)

			if val, ok := runtime.ReduceExpr(bexpr, parser.GlobalContext); ok {

				expr = ast.Expr(val)

			} else {
				// wrap the existing expression with the new binary expression object
				expr = ast.Expr(bexpr)
			}
		} else {
			panic(SyntaxError{
				Reason:      "Expecting term on the right side",
				ActualToken: parser.peek(),
				File:        parser.File,
			})
		}
		rightTok = parser.peek()
	}
	return expr
}
Exemple #2
0
/*
The operator precedence is described here

@see http://introcs.cs.princeton.edu/java/11precedence/
*/
func (parser *Parser) ParseCondition() ast.Expr {
	debug("ParseCondition")

	// Boolean 'Not'
	if tok := parser.accept(ast.T_LOGICAL_NOT); tok != nil {
		var logicexpr = parser.ParseLogicExpr()
		return ast.NewUnaryExpr(ast.NewOpWithToken(tok), logicexpr)
	}
	return parser.ParseLogicExpr()
}
Exemple #3
0
/*
ParseMediaType returns Ident Node or UnaryExpr as ast.Expr
*/
func (parser *Parser) ParseMediaType() *ast.MediaType {
	if tok := parser.acceptAnyOf2(ast.T_LOGICAL_NOT, ast.T_ONLY); tok != nil {
		var mediaType = parser.expect(ast.T_IDENT)
		return ast.NewMediaType(ast.NewUnaryExpr(ast.NewOpWithToken(tok), mediaType))
	}

	var tok = parser.peek()
	if tok.Type == ast.T_PAREN_OPEN {
		// the begining of the media expression
		return nil
	}

	var expr = parser.ParseExpr(false)
	if expr != nil {
		return ast.NewMediaType(expr)
	}

	// parse media type fail
	return nil
}