Calibre 语法/解析报错:Syntax error near 速查
更新时间:2026-10-22。FAQ 速查页,属于 EDA 工具排错系列。Calibre(Siemens EDA 的物理验证工具,DRC/LVS/PEX 三件套)启动后做的第一件事,是把工艺厂给的 SVRF rule deck 和你的 runset 从头解析一遍——这一步不过,一条版图都不会检查。SVRF(Standard Verification Rule Format)是声明式规则语言,不是 Tcl 也不是 HDL,拿写脚本的习惯去改 deck(行尾多一个空格、用
#写注释、把命令放错段落)最容易踩解析报错。rule deck 的五段结构见 Calibre SVRF rule deck 解剖,验证流程全貌见 Calibre 物理验证实操。同系列「文件找到了但名字对不上」见 Calibre 模块/单元找不到,本篇只管「文件在读、但读不下去」。
本文要回答的问题
- transcript 里的
Syntax error near "{" at line N指向的那行明明没问题,真正断点在哪? Unknown rule statement和unexpected token分别意味着 deck 哪里写错了?- 行尾反斜杠续行为什么会因为一个空格失效?SVRF 里能不能用
#写注释? - 工艺厂原版 deck 能跑,自己 INCLUDE 一段就报错,是方言、版本还是变量问题?
- DRC 能跑的 runset 换成
calibre -lvs就报一堆命令非法,为什么?
一、报错原文与典型现象
Calibre 的解析报错全部进 transcript(启动目录下的 .drc.results/.lvs.report 或重定向的 log),统一长着五星前缀,且带文件名和行号。以下是四类典型文案,规则名与文件名已占位:
1. token 级语法错(最高频,行号是「解析器发现不对」的位置,不一定是真正出错的位置):
***** ERROR: Syntax error near "{" at line 142 of file "proj_rules.m1.svrf".
***** ERROR: Unexpected token "0.06" encountered while parsing statement "M1.S.1".2. 关键字/规则名不认识:
***** ERROR: Unknown rule statement "EXTRNAL" encountered while parsing rules file.
***** ERROR: "M1.S.1" is not a recognized SVRF command or previously defined rule name.3. 变量没定义、命令放错 deck 段:
***** ERROR: Undefined variable "MY_RULE_HOME" encountered in INCLUDE statement.
***** ERROR: "LVS REPORT" is not a valid command in DRC rule context.4. 文件根本没能按文本解析(往往伴随大面积连环报错,第一条才是根因):
***** ERROR: Illegal character encountered at line 1 of file "proj_rules.svrf".
***** ERROR: End of file reached while scanning for closing quote starting at line 87.第一条判据:看 near 后面的 token 和行号——指到 {、引号、数字这类符号,八成是前面的括号/引号/续行符断了;指到一个像关键字的单词,查拼写和命令所属段落;第一条就是 Illegal character 或 line 1,直接怀疑 BOM、CRLF 或全角字符,不用往后看。
二、报错现象到根因总览
| 报错现象 | 可能原因 | 处置 |
|---|---|---|
| Syntax error near "{" / near 引号 | 括号或引号不配对,真正缺口在前面 | 从行号往上逐行核对 {} 与成对引号 |
| 报在行尾续行之后,下一行内容被当独立语句 | 反斜杠 \ 后带了空格或 \r,续行失效 | 删尾空格,dos2unix 统一 LF |
| Unknown rule statement | SVRF 关键字拼错,或自定义层/规则名与关键字撞名 | 照 SVRF 手册核对拼写,自定义名避开保留字 |
| Undefined variable / 变量名原样出现 | VARIABLE 未定义、定义顺序在后,或环境变量没 export | 先 VARIABLE 赋值再引用;shell 里 echo 校验 |
整段规则被当报错,# 开头注释行触发 | 误用 HDL/shell 的 # 注释,SVRF 注释是 // | 全部改 //,规则说明用 // @ |
| 原版 deck 能跑,INCLUDE 自家片段就挂 | 片段按别的 deck 方言/Calibre 版本写,语法不兼容 | 对照当前版本 SVRF 手册改写,不跨版本抄语法 |
| DRC runset 换 -lvs/-pex 报命令非法 | LVS/PEX 专属命令出现在 DRC 上下文 | 按运行模式分段,命令放对 deck 段 |
| Illegal character / line 1 就报错 / 连环错 | BOM、CRLF、Tab 被改、全角括号逗号混入 | 去 BOM、转 LF、全角符号改半角 |
| 数组下标、正则/字符串匹配处报 token 错 | 数组未声明/越界,正则分隔符或引号嵌套写错 | 先声明再用,正则与字符串各用各的引号 |
三、逐条排查展开
第一步:从报错行号往上找,而不是只盯着那一行。 SVRF 是自由格式语言,一条检查语句用花括号包着、还可以跨行:
// @ M1 最小间距 0.06 um
M1.S.1 { EXTERNAL m1 < 0.06 ABUT < 90 SINGULAR }解析器读到第 142 行的 { 才发现栈对不上,真正少一个 } 或引号的位置可能在几十行之前。做法是从行号往上逐行核对:每个 { 都有 }、每对双引号都闭合、规则名行与花括号之间没有被插入半截语句。编辑器开括号配对高亮,把可疑函数段整体折叠一遍,缺口一目了然。
第二步:查行尾反斜杠后面有没有「看不见的东西」。 SVRF 长语句用行尾 \ 续行,规则极硬:反斜杠必须是该行最后一个字符。它后面跟一个空格、一个 Tab,或 Windows 编辑后跟着 \r(CRLF 行尾),续行就失效——下一行被当成独立语句解析,报错落在下一行的第一个 token 上,行本身怎么看都对。这正是「报错位置说谎」的头号场景:
sed -n '85,90p' proj_rules.svrf | cat -A # 行尾显示为 \ 空格$ 或 \^M$ 即中招
dos2unix proj_rules.svrf顺手在输出里认全角字符:全角括号 ()、全角逗号 ,、中文引号出现在 SVRF 语句里,解析器一律按非法字符处理。
第三步:注释符只有 //,没有 #。 从 Verilog 或 shell 习惯带过来的 # 在 SVRF 里不是注释起始,整行会被当成语句扫描,通常报 Unknown rule statement 或 token 错。SVRF 注释一律 //;以 // @ 开头的行会被提取为规则说明进违例报告(deck 解剖篇讲过这个机制),临时注释掉大段规则时也用逐行 //,不要尝试 C 风格 /* */。
第四步:变量先定义后使用,环境变量在「启动 calibre 的 shell」里验。 SVRF 用 VARIABLE 做字符串替换,典型写法是先赋值、再在 INCLUDE 或路径里引用:
VARIABLE MY_RULE_HOME "/proj/chip/rules"
INCLUDE "$MY_RULE_HOME/common/stack.svrf"变量没定义、或 VARIABLE 语句排在引用之后,解析到 INCLUDE 时变量名原样留在路径里(报 Undefined variable,或下游文件找不到)。引用 shell 环境变量同理:交互终端里 export 过、回归脚本里没有,是固定事故形态——在启动 calibre 的那个 shell 里 echo $MY_RULE_HOME 验证,别在桌面上验。
第五步:INCLUDE 片段挂了,查方言、版本和段落归属。 工艺厂原版 deck 能跑、你在末尾或项目段 INCLUDE 自己一段就报错,三种常见不匹配:一是片段从别的工艺/别的 Calibre 版本抄来,用了当前版本不认的语法(新版语句在老版本解析器里直接 unexpected token);二是把 LVS/PEX 专属命令(LVS REPORT、DEVICE/CONNECT 段、PEX 控制语句)放进了用 calibre -drc 跑的 deck,解析器按 DRC 上下文审,判「命令在此上下文非法」;三是片段引用了主 deck 里定义的层名或派生层,但 INCLUDE 位置在那些定义之前。判据是最小 deck 二分:把嫌疑段单独 INCLUDE 进一个只留环境段的最小 deck,能复现就与工程其余部分无关,再逐小段注释收敛。
第六步:line 1 或满屏连环报错,先治编码。 文件开头带 UTF-8 BOM、Windows 保存成 CRLF、或从网页/邮件粘贴带入全角标点,解析器在第一条语句之前就撞上非法字节,之后的报错全是连锁反应,没有阅读价值。处置固定一套:去 BOM、dos2unix 转 LF、全角符号改半角,然后删掉本轮 run 目录干净重跑——只看重跑后的第一条报错。数组与正则类小众语法问题顺带一查:数组型变量先声明再下标引用,正则/属性匹配里分隔符与字符串引号各自成对,别把正则斜杠和 SVRF 的 // 注释混写在一行。
下面这张决策树把上面六步压成一条收敛路径,任何一层命中就在那一层修,不要跳着改 deck:
读这张图抓住「先符号、后语义,先就近、后 include 链」:红色入口是报错本身,两个蓝色节点是排查动作(行号向上追、最小 deck 二分),橙色是动手修复,紫色是干净复验。七成的解析报错死在第一层——括号引号与续行符;剩下三成里,INCLUDE 片段的方言/版本与命令放错段占大头,编码问题用「第一条是不是 Illegal character」一句话就能排除。
四、预防与纪律
- 改 deck 只在尾部项目段动:工艺厂原文一行不改,自定义规则用统一前缀追加并集中 INCLUDE,解析出错时嫌疑范围天然只剩自己的段落。
- 编辑器统一 Unix 换行、去 BOM、显示不可见字符:仓库配
.gitattributes强制*.svrf text eol=lf,行尾空格在提交钩子中拦掉。 - 注释只用
//,符号只敲半角:把「SVRF 没有#注释、没有/* */」写进项目组 deck 编写约定。 - 变量定义集中在 deck 头部:VARIABLE 与环境相关 INCLUDE 固定放最前,引用永远在定义之后;回归脚本启动前打印并
ls关键 include 文件。 - 跨版本/跨工艺抄语法先查手册:不把别的 deck 片段不加审查地 INCLUDE 进来;DRC、LVS、PEX 命令按运行模式分段维护。
- 改一处、干净重跑一次、只认第一条报错:连环报错不逐条修,编码和配对问题修完后先让解析器重新说话。
这一篇在知识体系里的位置
本篇是 EDA 排错速查簇的一员,总入口见 开源 EDA 报错排错中心;上游机制是 Calibre SVRF rule deck 解剖(看懂五段骨架才知道命令该放哪一段),流程背景见 Calibre 物理验证实操。解析通过之后的失败属于下游:文件/单元名对不上见 Calibre 模块/单元找不到。数字侧同构问题(语言模式、宏、CRLF 续行)可对照阅读 Design Compiler 语法解析报错:VER- 错误速查。
一句话总结
Calibre 的 SVRF 解析报错先看 near 的 token 与行号:指到符号就向上追括号引号配平和行尾反斜杠(其后一个空格或 \r 就让续行失效),指到单词查关键字拼写、VARIABLE 定义顺序与命令是否放错 deck 段,注释只认 // 不认 #;报错行本身正常就用最小 deck 二分 INCLUDE 链,查方言版本与片段位置,line 1 或连环报错先治 BOM/CRLF/全角字符;防复发靠「Unix 换行 + 只改项目段 + 变量集中定义 + 干净重跑只认第一条」四条纪律。