How GaiaX’s Cross‑Platform Expression Engine Achieves Fast, Stable UI Rendering
This article explains GaiaX’s cross‑platform expression engine, covering its design, LR(1) grammar‑based parsing, syntax‑tree construction, C++ core implementation, Android JNI and iOS bridge integration, unified data types, performance benchmarks, and how it ensures consistent, high‑performance UI rendering on mobile devices.
Preface
GaiaX is a high‑performance cross‑platform rendering engine developed by the Youku Application Center, open‑sourced to improve multi‑device UI component development efficiency.
Expression Overview
Expressions in GaiaX templates provide data retrieval and calculation capabilities, serving as the logical foundation for dynamic UI binding.
{
"data":{
"gx-expression-value":{
"value": "$data.text"
},
"gx-expression-calculate":{
"value": "1+2*3%3+$data.num"
},
"gx-expression-function":{
"value": "Size($data.array)"
}
}
}The engine supports value extraction, function evaluation, and arithmetic expressions, implemented in C++ for consistency across platforms.
Technical Design
Expression Parsing Process
Parsing follows the classic compiler steps: lexical analysis, syntax analysis, and semantic analysis, focusing on the first three phases.
Lexical Analysis : Scans the character stream and tokenizes it.
Syntax Analysis : Builds syntax phrases and validates structure, producing a syntax tree.
Semantic Analysis : Checks semantic rules using the syntax tree and symbol table.
GaiaX uses an LR(1) grammar for syntax analysis and integrates semantic checks during tree construction.
Syntax Tree Construction – LR(1) Grammar
LR(1) parsing reads input left‑to‑right, performs rightmost derivation, and looks ahead one token, offering fewer restrictions and faster error detection than LL(k) or precedence parsers.
LR(1) Grammar
Symbol
Meaning
L
Left‑to‑right scan
R
Rightmost derivation
(1)
Lookahead of one token
Key concepts:
Name
Meaning
Derivation
Transform string x to y via a rule (x→y)
Reduction
Reverse of derivation; y reduces to x when rule x→y is applied
GaiaX Expression Syntax Tree Construction Flow
The grammar for four‑operator arithmetic is:
S -> S + E # addition
| S - E # subtraction
| E
E -> E * num # multiplication
| E / num # division
| numExample expression a*b+c demonstrates that multiplication has higher precedence because its reduction occurs deeper in the LR(1) parse tree.
Syntax Tree Construction Process
After lexical analysis, the parser repeatedly pushes tokens onto a stack and reduces them according to the parsing table, ultimately producing a complete syntax tree where deeper nodes represent higher‑priority operations.
Cross‑Platform Implementation Design
Expressions can be invoked from both Android and iOS. The C++ core calls platform‑specific code via two scenarios:
C++ Calls Android via JNI
Android uses JNI to bridge C++ and Java/Kotlin. The GXAnalyzeAndroid class implements the required interfaces, and native methods such as getSourceValueFromJava and getFunctionValueFromJava forward calls to Java.
static jlong getSourceValueFromJava(string valuePath, jobject source, jobject object_in) {
JNIEnv *env = getJNIEnv();
if (env != nullptr) {
jclass clazz = env->GetObjectClass(object_in);
jfieldID analyze_fieldID = env->GetFieldID(clazz, "computeExtend", "Lcom/expressionDir/GXAnalyzeAndroid$IComputeExtend;");
jobject jobject = env->GetObjectField(object_in, analyze_fieldID);
jclass analyzeJni = env->GetObjectClass(jobject);
jmethodID getArrId = env->GetMethodID(analyzeJni, "computeValueExpression", "(Ljava/lang/String;Ljava/lang/Object;)J");
jlong res = env->CallLongMethod(jobject, getArrId, str2jstring(env, valuePath.c_str()), source);
env->DeleteLocalRef(clazz);
env->DeleteLocalRef(jobject);
env->DeleteLocalRef(analyzeJni);
return res;
}
return 0L;
}The C++ layer defines abstract virtual methods in GXAnalyze, which GXJniAnalyze implements to delegate calls to the Java side.
class GXJniAnalyze : public GXAnalyze {
public:
long getSourceValue(string valuePath, void *source) override {
jobject dataSource = static_cast<jobject>(source);
return getSourceValueFromJava(valuePath, dataSource, globalSelf);
}
};
extern "C" JNIEXPORT jlong JNICALL Java_com_alibaba_gaiax_analyze_GXAnalyze_getResultNative(JNIEnv *env, jobject thiz, jobject self, jstring expression, jobject data) {
GXJniAnalyze *jAnalyze = getJniAnalyze(env, self);
long res = jAnalyze->getExpressionResult(jstring2str(env, expression), data);
return (jlong)res;
}C++ Calls iOS via Bridge
On iOS, a GXAnalyzeBridge Objective‑C class implements the virtual methods, and GXAnalyzeImpl inherits from GXAnalyze to forward calls to the bridge.
@interface GXAnalyzeBridge : NSObject
- (long)getFunctionValue:(NSString *)funName paramPointers:(long *)paramPointers paramsSize:(int)paramsSize;
- (long)getSourceValue:(NSString *)valuePath source:(id)source;
@end class GXAnalyzeImpl : public GXAnalyze {
public:
long getSourceValue(string valuePath, void* source);
long getFunctionValue(string funName, long* paramPointers, int paramsSize, string source);
};Unified Data Type
To reconcile differing platform data representations, GaiaX defines a GXValue class that can hold integers, floats, strings, arrays, maps, etc.
class GXValue {
public:
int64_t tag;
int32_t int32; // Bool 1/0
float float64; // Float
int64_t intNum; // Long
void *ptr; // Array, Map
char *str; // String
};Performance and Stability
Implemented in C++, the engine delivers low latency. Benchmarks on Android devices show sub‑millisecond execution for various expression types.
Computation Type
Expression
Time per Call
Single Value
10000
0.017ms
Value Retrieval
$data.xxx
0.024ms
Data Source
$$
0.019ms
Numeric Operation
10%5
0.029ms
ternary
true ? 1 : 2
0.048ms
Function
Size('1000')
0.029ms
Complex Nested $data.b % 5 > 2 ? $data.b % 5 : 1 0.060ms
Conclusion
GaiaX’s expression engine leverages compiler theory to ensure cross‑platform consistency and high performance, though further optimizations in reduction algorithms and data structures remain future work.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
