Add ABB120 demo suite and docs

This commit is contained in:
wangdequan
2026-06-28 20:58:18 +08:00
parent 84a5b54195
commit 65187499d6
820 changed files with 215410 additions and 211 deletions

View File

@@ -168,7 +168,7 @@ label jump
movej movel movec run_path run_operation
set_tool set_frame set_speed set_zone
wait pulse timer
io true false all any rising falling changed
io true false and or not mod all any rising falling changed
trap interrupt enable disable raise alarm try catch finally
task sync
post_hint source defaults point event before after at
@@ -277,9 +277,163 @@ persistent real counter = 0
3. `var` 默认为局部变量。
4. 类型可以显式写出,自动生成程序建议显式写出。
## 7. 坐标、工具和目标点
## 7. 表达式与运算
### 7.1 工具
GRL 表达式是数据声明、运动参数、路径参数、IO 条件和流程控制的公共基础。首版按 ABB RAPID、FANUC LS/KAREL、KUKA KRL 共同具备的数学能力建模,优先保证同一 GRL 程序能稳定编译到统一 IR再由后处理器输出品牌程序。
### 7.1 语法范围
表达式必须支持:
1. 算术:一元 `+`、一元 `-`、二元 `+``-``*``/``mod`
2. 比较:`==``!=``<``<=``>``>=`
3. 逻辑:`and``or``not`;可兼容 `&&``||``!` 作为输入别名IR 中统一为 GRL 关键字。
4. 括号:`(...)` 显式改变优先级。
5. 函数调用:`callee(args...)`,参数内部允许完整表达式。
6. 单位后缀:可作用于数字字面量、标识符、函数调用或括号表达式,例如 `100 mm``blend_base mm``sqrt(90000) mm``(10 + 5) deg`
7. 现有结构表达式数组、对象、构造器调用、标识符引用、IO 引用和 `offset` 表达式必须继续兼容。
优先级从高到低:
| 层级 | 运算 |
| --- | --- |
| 1 | 函数调用、对象、数组、括号、构造器、offset |
| 2 | 一元 `+``-``not``!` |
| 3 | `*``/``mod` |
| 4 | `+``-` |
| 5 | `<``<=``>``>=` |
| 6 | `==``!=` |
| 7 | `and``&&` |
| 8 | `or``||` |
### 7.2 内置常量和函数
首版内置常量:
| 名称 | 含义 |
| --- | --- |
| `pi` | 圆周率 |
| `e` | 自然常数 |
首版内置函数:
| 类别 | 函数 |
| --- | --- |
| 三角函数 | `sin``cos``tan``asin``acos``atan``atan2` |
| 数值函数 | `sqrt``abs``pow``min``max``clamp``floor``ceil``round` |
函数规则:
1. `sin/cos/tan` 接收角度量;带 `deg``rad` 单位时归一化为弧度,纯数按弧度处理。
2. `asin/acos` 接收无单位数值,定义域为 `[-1, 1]``atan` 接收无单位数值;`atan2(y, x)` 的两个参数必须同维度或均为无单位数值。
3. `asin/acos/atan/atan2` 返回角度量;在 `pose(...)` 姿态项或 `joint_target.joints` 等角度上下文中可直接使用。
4. `sqrt` 首版只要求支持无单位数值或编译器明确支持的上下文,负数必须报定义域错误。
5. `min/max/clamp` 的参数必须维度兼容;`clamp(value, min, max)` 的边界顺序错误应给出 diagnostic。
6. 函数参数数量必须严格检查,例如 `atan2` 为 2 个参数,`clamp` 为 3 个参数。
### 7.3 单位和求值语义
数值求值采用统一 SI 归一化:
| GRL 输入 | IR/KDL 归一化 |
| --- | --- |
| `mm` | m |
| `m` | m |
| `mm/s` | m/s |
| `mm/s2` | m/s2 |
| `deg` | rad |
| `rad` | rad |
| `%` | 0 到 1 的比例 |
| `s` | s |
| `ms` | s |
| `kg` | kg |
规则:
1. 同维度数值可以相加、相减和比较,结果保留该维度并归一化。
2. 纯数可以参与乘除;维度乘除首版只允许编译器明确支持的上下文,避免产生复杂复合单位。
3. 不同维度相加、相减或比较必须报错,例如 `10 mm + 2 s`
4. 构造器可以提供默认上下文单位:`linear(...)` 默认 `mm/s``angular(...)` 默认 `deg/s``z(...)` 默认 `mm``pose(...)` 前三项默认 `mm`、后三项默认 `deg``joint_target.joints` 默认 `deg``timeout/duration` 默认 `s`
5. 因此 `linear(100 + 50 mm/s)``linear` 速度上下文中等价于 `linear(150 mm/s)`;自动生成程序推荐输出显式单位,减少人工歧义。
### 7.4 编译期求值位置
常量表达式必须在编译阶段求值,并把结果写入 Semantic IR / KDL request而不是把表达式字符串传到运动规划层。
必须支持的求值位置:
1. 数据声明 initializer`const``persistent`、需要静态初值的 `var`
2. `speed``linear(...)``joint(...)``angular(...)``acc ...` 参数。
3. `zone``fine``z(...)``cnt(...)`
4. `pose(...)``poseq(...)``robot_config(...)`
5. `joint_target { joints: [...] }`
6. `pose_target { pose: ... }`
7. `tool { tcp: ..., mass: ... }``frame { origin: ... }`
8. path `defaults``source` 属性和 path point 内联 `speed``zone``tool``frame``via``target` 参数。
9. path event 的 `distance`
10. `wait ... timeout ...``pulse ... duration ...` 中的时间常量。
11. operation `process` 中需要数值常量的工艺参数。
12. `switch case` 值。
比较和逻辑表达式也必须进入 AST。纯常量比较/逻辑可在编译期折叠;依赖 IO、变量或运行态状态的条件先保留为结构化控制表达式供虚拟控制器和后续品牌映射使用。
### 7.5 示例
```text
const real blend_base = 5 + 5
const speed v_pick = linear(100 + 50 mm/s)
const speed v_safe = linear(max(50 mm/s, 200 mm/s / 2))
const zone z_app = z(clamp(blend_base mm, 1 mm, 50 mm))
target home = joint_target {
joints: [0 deg, (10 + 5) deg, -90 deg, 0 deg, 0 deg, 0 deg]
}
target pick = pose_target {
pose: pose(400 + 50 mm, 20 * 2 mm, sqrt(90000) mm, 0 deg, 0 deg, atan2(1, 1))
}
wait io.ai[2] > sin(30 deg) timeout 1 + 1 s
```
编译期结果要求:
1. `v_pick` 进入 IR 后为 `linear`,速度 `0.15 m/s`
2. `z_app` 进入 IR 后为 `distance`,距离 `0.01 m`
3. `home.joints[1]` 进入 IR 后为 `15 deg` 对应的弧度值。
4. `pick.pose.position[0]` 进入 IR 后为 `0.45 m`
5. `atan2(1, 1)` 进入姿态上下文后为 `45 deg` 对应的弧度值。
### 7.6 诊断
运算功能必须输出稳定 diagnostic
| code | 场景 |
| --- | --- |
| `GRL_EXPR_PARSE` | 表达式语法错误或括号不匹配。 |
| `GRL_EXPR_UNKNOWN_SYMBOL` | 常量求值遇到未知标识符。 |
| `GRL_EXPR_UNKNOWN_FUNCTION` | 未知函数。 |
| `GRL_EXPR_ARITY` | 函数参数数量错误。 |
| `GRL_EXPR_DOMAIN` | 数学定义域错误,例如 `sqrt(-1)``acos(2)`。 |
| `GRL_EXPR_DIV_ZERO` | 除零。 |
| `GRL_EXPR_UNIT_MISMATCH` | 单位维度不兼容。 |
| `GRL_EXPR_NON_CONSTANT` | 需要常量的位置出现运行时表达式。 |
| `GRL_EXPR_UNSUPPORTED_RUNTIME` | 后处理暂不支持的复杂运行时表达式。 |
每个 diagnostic 必须包含 severity、message、source range并能通过 source map 定位到 GRL 源文件行列。
### 7.7 跨品牌边界
首版跨品牌输出不直接翻译复杂表达式字符串,而是优先输出编译期折叠后的常量:
1. `linear(100 + 50 mm/s)` 输出为各品牌可表达的具体速度值。
2. `z(clamp(...))` 输出为具体 ABB zone、FANUC CNT 或 KUKA 近似 blend。
3. runtime 条件表达式如果后处理器无法保真映射,必须进入转换报告,不得静默丢失。
4. 品牌专用数学函数、控制器系统变量和复杂运行时表达式不作为首版公共能力,后续通过 post/import report 增量支持。
## 8. 坐标、工具和目标点
### 8.1 工具
```text
persistent tool gripper = tool {
@@ -289,7 +443,7 @@ persistent tool gripper = tool {
}
```
### 7.2 工件坐标
### 8.2 工件坐标
```text
persistent frame fixture = frame {
@@ -297,7 +451,7 @@ persistent frame fixture = frame {
}
```
### 7.3 关节目标点
### 8.3 关节目标点
```text
target home = joint_target {
@@ -307,7 +461,7 @@ target home = joint_target {
`joint_target` 主要用于 `movej`,后处理可映射到 ABB `jointtarget`、KUKA `E6AXIS` 或 FANUC 关节位置数据。
### 7.4 笛卡尔目标点
### 8.4 笛卡尔目标点
```text
target pick = pose_target {
@@ -330,7 +484,7 @@ pose(x, y, z, rx, ry, rz)
poseq(500 mm, 120 mm, 300 mm, 0, 0, 0.7071068, 0.7071068)
```
### 7.5 偏移目标点
### 8.5 偏移目标点
```text
var pose_target approach = pick offset z 100 mm
@@ -344,9 +498,9 @@ var pose_target p3 = pick offset_in tool z -50 mm
var pose_target p4 = pick offset_in frame fixture x 100 mm
```
## 8. 速度和过渡
## 9. 速度和过渡
### 8.1 速度
### 9.1 速度
```text
const speed v_joint_fast = joint(80 %)
@@ -367,7 +521,7 @@ const speed v_orient = angular(90 deg/s)
const speed v_slow = linear(100 mm/s, acc 500 mm/s2)
```
### 8.2 过渡
### 9.2 过渡
```text
const zone z_fine = fine
@@ -384,9 +538,9 @@ const zone z_cont = continuous
3. `cnt(percent)`:以百分比表示连续过渡,便于映射 FANUC `CNT`
4. `continuous`:允许连续通过,实际过渡由后处理器或虚拟控制器策略决定。
## 9. 运动指令
## 10. 运动指令
### 9.1 基本语法
### 10.1 基本语法
```text
movej TargetExpr [speed Speed] [zone Zone] [tool Tool] [frame Frame]
@@ -402,7 +556,7 @@ movel pick speed linear(300 mm/s) zone z10
movec via arc_mid target arc_end speed linear(150 mm/s) zone fine
```
### 9.2 MOVEJ 语义
### 10.2 MOVEJ 语义
`movej` 表示关节空间运动。机器人按各轴关节角度差分运行关节同起同停TCP 轨迹不要求是直线。
@@ -416,7 +570,7 @@ movec via arc_mid target arc_end speed linear(150 mm/s) zone fine
- FANUC`J P[...]`
- KUKA`PTP`
### 9.3 MOVEL 语义
### 10.3 MOVEL 语义
`movel` 表示 TCP 直线运动。TCP 沿起点到终点的空间直线运行,关节角由每个 TCP 采样点 IK 求解。
@@ -430,7 +584,7 @@ movec via arc_mid target arc_end speed linear(150 mm/s) zone fine
- FANUC`L P[...]`
- KUKA`LIN`
### 9.4 MOVEC 语义
### 10.4 MOVEC 语义
`movec` 表示 TCP 圆弧运动。TCP 从当前点出发,经过 via 点,到达 target 点,沿圆弧运行,关节角由每个圆弧采样点 IK 求解。
@@ -445,7 +599,7 @@ movec via arc_mid target arc_end speed linear(150 mm/s) zone fine
- FANUC`C P[...]`
- KUKA`CIRC`
### 9.5 当前工具和当前坐标
### 10.5 当前工具和当前坐标
```text
set_tool gripper
@@ -463,11 +617,11 @@ set_zone z10
编译到 IR 时,所有运动必须有确定的 `tool``frame``speed``zone`
## 10. Path 语法
## 11. Path 语法
Path 是自动离线编程的核心对象。CAD 曲线、规划点、示教点、工艺模板应优先生成 Path而不是直接生成散乱运动语句。
### 10.1 基本语法
### 11.1 基本语法
```text
path pick_path {
@@ -484,7 +638,7 @@ path pick_path {
}
```
### 10.2 圆弧点
### 11.2 圆弧点
```text
path arc_path {
@@ -500,7 +654,7 @@ path arc_path {
}
```
### 10.3 来源元数据
### 11.3 来源元数据
```text
path curve_032_generated {
@@ -532,7 +686,7 @@ path curve_032_generated {
3. 重新生成程序。
4. 报告中定位到 CAD 曲线或工艺对象。
### 10.4 Path event
### 11.4 Path event
```text
event before p001 io.do[10] = true
@@ -547,7 +701,7 @@ event at p005 distance -20 mm pulse io.do[20] duration 100 ms
3. `at ... distance`:相对路径点提前或滞后触发,首版可编译为最近采样点事件。
4. 后处理到品牌程序时,若品牌不支持精确路径触发,应生成转换报告。
### 10.5 `run_path`
### 11.5 `run_path`
```text
proc main()
@@ -562,7 +716,7 @@ end
3. event 变为 IO/Wait/Process IR。
4. 保留 source map调试时可从程序行定位到路径点。
## 11. Operation 语法
## 12. Operation 语法
Operation 表达工艺语义,比 Path 更高一层。
@@ -614,9 +768,9 @@ end
3. 执行 `end_action`
4. 保留工艺参数,供仿真 UI、报告和后处理使用。
## 12. IO 与等待
## 13. IO 与等待
### 12.1 IO 地址
### 13.1 IO 地址
```text
io.di[1]
@@ -637,7 +791,7 @@ io.alias.clamp_closed
io.alias.gripper_close_cmd
```
### 12.2 IO 写入
### 13.2 IO 写入
```text
io.do[1] = true
@@ -645,7 +799,7 @@ io.go[1] = 16
io.ao[1] = 3.5
```
### 12.3 wait
### 13.3 wait
```text
wait io.di[1] == true
@@ -664,7 +818,7 @@ wait io.di[1] == true timeout 2 s on_timeout alarm "Clamp close timeout"
wait io.di[1] == true timeout 2 s on_timeout call recover_clamp()
```
### 12.4 pulse
### 13.4 pulse
```text
pulse io.do[3] duration 200 ms
@@ -676,11 +830,11 @@ pulse io.do[3] duration 200 ms
2. 虚拟时间到达 duration 后自动复位。
3. trace 中必须记录置位和复位事件。
## 13. 流程控制
## 14. 流程控制
流程控制用于表达工艺分支、重试、配方选择、批量工位循环和异常恢复。GRL 新程序应优先使用结构化控制流;`label/jump` 主要用于兼容 FANUC TP/LS 等已有程序导入。
### 13.1 条件 `if / elseif / else`
### 14.1 条件 `if / elseif / else`
```text
if part_ok
@@ -711,7 +865,7 @@ if is_part_ready()
if recipe_id == 2 or recipe_id == 3
```
### 13.2 `while` 循环
### 14.2 `while` 循环
```text
while retry < 3
@@ -731,7 +885,7 @@ end
4. `continue` 跳过本轮剩余语句,进入下一轮条件判断。
5. 编译器建议对可能无限循环的 `while true` 给出 warning除非循环体内包含明确的 `break``return``raise``wait`
### 13.3 `for` 循环
### 14.3 `for` 循环
```text
for i = 0 to 9 step 1
@@ -763,7 +917,7 @@ end
4. `break``continue` 只影响当前最近一层循环。
5. 后处理到不支持结构化 `for` 的品牌时,可展开为标签和跳转,但必须保持 source map。
### 13.4 `switch / case / default`
### 14.4 `switch / case / default`
```text
switch recipe_id
@@ -798,7 +952,7 @@ end
6. 导出到 FANUC TP/LS 时,`switch` 可转换为 `SELECT`、条件跳转或 `LBL/JMP` 组合。
7. 导出到 ABB/KUKA 时,优先转换为品牌结构化分支。
### 13.5 `break` 和 `continue`
### 14.5 `break` 和 `continue`
```text
while true
@@ -821,7 +975,7 @@ end
2. `continue` 只能出现在 `while``for` 中。
3.`switch` 中不需要 `break` 防止贯穿,因为 GRL 默认不贯穿。
### 13.6 label 和 jump
### 14.6 label 和 jump
```text
label retry
@@ -841,9 +995,9 @@ end
4. 允许 `jump` 跳出块结构,但编译器应生成 warning。
5. 自动生成的新程序不应使用 `label/jump`,除非目标后处理配置要求 FANUC 风格输出。
## 14. 子程序和函数
## 15. 子程序和函数
### 14.1 `proc` 子程序
### 15.1 `proc` 子程序
`proc` 是无返回值子程序用于组织工艺步骤、运动流程、IO 流程和恢复逻辑。
@@ -869,7 +1023,7 @@ call pick_part(slot_id)
4. `return` 可以提前退出 `proc`,但不能携带返回值。
5. `proc main()` 是默认入口。一个模块中最多一个默认入口。
### 14.2 参数方向
### 15.2 参数方向
参数支持 `in``out``inout` 三种方向。未写方向时默认为 `in`
@@ -905,7 +1059,7 @@ call read_part(ok)
call increment_retry(retry)
```
### 14.3 `func` 函数
### 15.3 `func` 函数
`func` 有返回值,适合计算条件、选择目标点、计算偏移、读取配方参数。函数应尽量无副作用。
@@ -945,7 +1099,7 @@ movel slot_pose(slot_id) speed linear(200 mm/s) zone z10
4. `func` 默认不允许执行运动指令、`wait``pulse``run_path``run_operation`。编译器应把这类用法作为 error 或强 warning。
5. 如果确实需要带副作用的逻辑,应使用 `proc`
### 14.4 作用域和名称解析
### 15.4 作用域和名称解析
名称解析顺序:
@@ -962,7 +1116,7 @@ movel slot_pose(slot_id) speed linear(200 mm/s) zone z10
3. `for` 循环变量只在循环体内有效。
4. `label` 只在当前 `proc` 内有效。
### 14.5 子程序调用和后处理
### 15.5 子程序调用和后处理
后处理映射:
@@ -975,16 +1129,16 @@ movel slot_pose(slot_id) speed linear(200 mm/s) zone z10
如果目标品牌或输出格式不支持某种参数模式,后处理器必须生成转换报告,不能静默丢失语义。
## 15. 异常、报警和中断
## 16. 异常、报警和中断
### 15.1 alarm 和 raise
### 16.1 alarm 和 raise
```text
alarm "Part not detected"
raise E_PICK_FAILED
```
### 15.2 try/catch
### 16.2 try/catch
```text
try
@@ -998,7 +1152,7 @@ end
首版可先实现 `alarm``raise` 和简单 `catch`,复杂品牌错误恢复分阶段支持。
### 15.3 trap 和 interrupt
### 16.3 trap 和 interrupt
```text
trap emergency_stop()
@@ -1018,7 +1172,7 @@ disable interrupt e_stop
2. KUKA 可映射到 `INTERRUPT DECL``INTERRUPT ON/OFF` 等近似结构。
3. FANUC 首版可生成后台逻辑、条件监控或转换报告。
## 16. 多任务
## 17. 多任务
首版只定义语法,不要求完整实现多任务实时调度:
@@ -1032,9 +1186,9 @@ end
虚拟控制器可先按周期任务模拟;后处理时根据品牌能力生成后台任务或转换报告。
## 17. 品牌扩展和后处理提示
## 18. 品牌扩展和后处理提示
### 17.1 post_hint
### 18.1 post_hint
```text
post_hint abb {
@@ -1055,7 +1209,7 @@ post_hint kuka {
}
```
### 17.2 brand metadata
### 18.2 brand metadata
```text
@brand.abb {
@@ -1078,7 +1232,7 @@ post_hint kuka {
2. 通用虚拟控制器不应依赖品牌 metadata 才能执行。
3. 无法支持的品牌扩展必须进入转换报告。
## 18. 自动编程生成规则
## 19. 自动编程生成规则
自动生成 GRL 时,应遵循以下规则:
@@ -1108,9 +1262,9 @@ proc main()
end
```
## 19. 后处理映射规则
## 20. 后处理映射规则
### 19.1 ABB RAPID
### 20.1 ABB RAPID
| GRL | ABB RAPID |
| --- | --- |
@@ -1140,7 +1294,7 @@ movel pick speed linear(300 mm/s) zone z10 tool gripper frame fixture
MoveL pick, v300, z10, gripper\WObj:=fixture;
```
### 19.2 FANUC LS/TP 风格
### 20.2 FANUC LS/TP 风格
| GRL | FANUC |
| --- | --- |
@@ -1170,7 +1324,7 @@ movel P10 speed linear(300 mm/s) zone cnt(10)
L P[10] 300mm/sec CNT10 ;
```
### 19.3 KUKA KRL
### 20.3 KUKA KRL
| GRL | KUKA KRL |
| --- | --- |
@@ -1201,7 +1355,7 @@ $VEL.CP = 0.3
LIN XPICK C_DIS
```
## 20. 编译语义和 IR
## 21. 编译语义和 IR
编译管线:
@@ -1239,7 +1393,7 @@ interface MotionInstruction {
}
```
## 21. 语义检查
## 22. 语义检查
编译器必须检查:
@@ -1250,21 +1404,25 @@ interface MotionInstruction {
5. 圆弧三点是否重合或共线。
6. 工具、坐标系、速度、过渡是否可解析。
7. 单位是否正确。
8. IO 地址是否存在于 IO map 或允许范围
9. 子程序参数数量和类型是否匹配
10. `out` 参数是否在所有正常返回路径上赋值
11. `inout``out` 实参是否为可赋值左值
12. `func` 是否在所有正常返回路径上返回正确类型
13. `break``continue` 是否出现在合法结构内
14. `switch case` 是否为常量表达式,是否存在重复 case
15. `jump` 是否跳入非法块结构
16. `wait` 是否有可执行条件
17. Path 是否为空
18. Path point 名称是否重复
19. Operation 是否引用不存在的 Path
20. 目标点是否可达
21. 关节是否超限
22. 后处理目标品牌是否支持所用语义
8. 表达式优先级、括号、函数调用参数是否解析正确
9. 内置函数名称、参数数量、定义域和单位维度是否正确
10. 需要常量的位置是否只使用常量表达式
11. 除零、未知符号、未知函数和复杂运行时表达式是否产生稳定 diagnostic
12. IO 地址是否存在于 IO map 或允许范围
13. 子程序参数数量和类型是否匹配
14. `out` 参数是否在所有正常返回路径上赋值
15. `inout``out` 实参是否为可赋值左值
16. `func` 是否在所有正常返回路径上返回正确类型
17. `break``continue` 是否出现在合法结构内
18. `switch case` 是否为常量表达式,是否存在重复 case
19. `jump` 是否跳入非法块结构
20. `wait` 是否有可执行条件
21. Path 是否为空
22. Path point 名称是否重复
23. Operation 是否引用不存在的 Path。
24. 目标点是否可达。
25. 关节是否超限。
26. 后处理目标品牌是否支持所用语义。
诊断格式建议:
@@ -1275,7 +1433,7 @@ W3002: zone z50 is larger than segment length
W4001: KUKA post approximates GRL cnt(30) by C_DIS
```
## 22. EBNF 语法草案
## 23. EBNF 语法草案
以下是首版解析器可采用的简化 EBNF
@@ -1310,7 +1468,8 @@ path_item = defaults_block | source_block | path_point | path_event ;
defaults_block = "defaults" "{" { property } "}" ;
source_block = "source" "{" { property } "}" ;
path_point = "point" identifier motion_stmt ;
path_event = "event" ( "before" | "after" ) identifier statement ;
path_event = "event" ( ( "before" | "after" ) identifier
| "at" identifier "distance" expr ) statement ;
operation_decl = "operation" identifier "{"
"kind" ":" identifier
@@ -1379,18 +1538,34 @@ jump_stmt = "jump" identifier ;
param_list = param { "," param } ;
param = [ "in" | "out" | "inout" ] type identifier ;
arg_list = expr { "," expr } ;
const_expr = expr ;
duration = expr ;
length = expr ;
speed_expr = expr ;
zone_expr = expr ;
expr = literal
expr = or_expr ;
or_expr = and_expr { ( "or" | "||" ) and_expr } ;
and_expr = equality_expr { ( "and" | "&&" ) equality_expr } ;
equality_expr = relation_expr { ( "==" | "!=" ) relation_expr } ;
relation_expr = additive_expr { ( "<" | "<=" | ">" | ">=" ) additive_expr } ;
additive_expr = multiply_expr { ( "+" | "-" ) multiply_expr } ;
multiply_expr = unary_expr { ( "*" | "/" | "mod" ) unary_expr } ;
unary_expr = [ "+" | "-" | "not" | "!" ] postfix_expr ;
postfix_expr = primary_expr { unit_suffix | offset_clause } ;
unit_suffix = unit ;
primary_expr = literal
| identifier
| call_expr
| io_ref
| unary_expr
| binary_expr
| call_expr
| array
| object
| "(" expr ")" ;
call_expr = identifier "(" [ arg_list ] ")" ;
literal = number | string | "true" | "false" ;
```
## 23. 完整示例
## 24. 完整示例
```text
language grl 0.1
@@ -1488,7 +1663,7 @@ module Main
end
```
## 24. 实施优先级
## 25. 实施优先级
P0 必须实现:
@@ -1503,9 +1678,10 @@ P0 必须实现:
9. `call``return``break``continue`
10. `proc` 参数方向 `in/out/inout`
11. `func`、函数调用表达式和返回值检查。
12. `io.do/di``wait``pulse`
13. AST、语义检查、IR、source map
14. ABB、FANUC、KUKA 后处理原型
12. 表达式 parser、单位后缀、内置数学函数、三角函数和编译期常量求值
13. `io.do/di``wait``pulse`
14. AST、语义检查、IR、source map
15. ABB、FANUC、KUKA 后处理原型。
P1 扩展:
@@ -1517,7 +1693,7 @@ P1 扩展:
6. 品牌程序导入。
7. 复杂品牌扩展和转换报告。
## 25. 参考资料
## 26. 参考资料
1. ABB RAPID Technical Reference ManualRAPID Instructions, Functions and Data Types
https://library.e.abb.com/public/b227fcd260204c4dbeb8a58f8002fe64/Rapid_instructions.pdf