《System语言详解》——5. 语言元素

英文原文: http://sourceware.org/systemtap/langref/Language_elements.html

译者:林永听

注:本系列文章为作者连载作品,请勿转载,否则视为侵权。

 

5 语言元素

5.1 标识符

标识符用于命名变量和函数。它是一个字母和数字组成的串,可以包含下划线(_) 和美元符号($) 。除了美元符号作为合法字符外,它和C 标识符的语法一样。以美元符号开头的标识符解释为目标软件变量的引用,而不是SystemTap 脚本变量。标识符不能以数字开始。

5.2 数据类型

SystemTap 语言仅有数种数据类型,均不需要类型声明。变量的类型可从它的使用环境中推导出来。为了支持类型推导,转换器强制要求函数的参数和返回值,数组下标和值在使用时要保证类型一致。字符串和整数之间不存在隐式类型转换。标识符在使用时,类型不一致的相关使用都会产生一个错误信号。

5.2.1 字面值

字面值有两种,分别是字符串和整数。字面值可以是十进制,八进制或十六进制,遵照C 语言的标记法,不需要指定类型后缀(如LU )。

5.2.2 整数

整数可以是十进制, 十六进制, 或者八进制,C 语言标记法相同。整数是一个64 位有符号变量,尽管分析器可以接受(同时会回 )大于2^63 且小于2^64 的整数(译者注:一个64 位有符号整型可以储存的整数范围是[-2^63,2^63 ),因此大于2^63 且小于2^64 的整数会回 卷成相应的负数 )。

5.2.3 字符串

字符串被括在引号(”” )内,反斜杠转义码均按标准C 的转义字符进行解释。字符的长度不能超过MAXSTRINGLEN ,关于字符串长度或其它限制,请参阅1.6 节。

5.2.4 关联数组

请参阅7 节。

5.2.5 统计变量

请参阅8 节。

5.3 分号

分号是一个条空语句,即什么事情也不做。分号是可选的,用作语句的分隔符,通常有助于检查语法错误和消除语法的二义性。

5.4 注释

SystemTap 脚本支持下述三种注释:

# ... shell style, to the end of line

// ... C++ style, to the end of line

/* ... C style ... */

5.5 空白符

正如C 一样,空格,制表符,回车,换行和注释均被视为空白,分析器直接忽略。

5.6 表达式

SystemTap 提供大量的运算符,并且它的用法,语义和优先级均与Cawk 相同。算术运算符按C 语言中的有符号整数运算规则执行。如果分析器检测到除数为0 或发生溢出,将产生一个错误。这些运算符(分类)罗列在下述各子章节。

5.6.1 二元数值运算符

* / % + - >> << & ^ | && ||

5.6.2 二元字符串运算符

. ( 字符串串接)

5.6.3 数值赋值运算符

= *= /= %= += -= >>= <<= &= ^= |=

5.6.4 字符串赋值运算符

= .=

5.6.5 一元数值运算符

+ - ! ~ ++ -

5.6.6 二元数值/ 字符串比较运行算

< > <= >= == !=

5.6.7 三元运算符

cond ? exp1 : exp2

5.6.8 组合运算符

( exp )

5.6.9 函数调用

函数调用的语法形式如下:

fn ([ arg1, arg2, ... ])

5.6.10 $ptr->member

Ptr 是探测下文中的变量,一个内核指针。

5.6.11 <value> in <array_name>

如果数组包含指定下标的元素,那么上述表达式求值结果为真。

5.6.12 [ <value>, ... ] in <array_name>

下标的个数必须与数组定义时指定的下标个数一致。

5.7 stap 命令行传递过来的字面值

字符值要么是由引号包含的字符串,要么是整数。关于整数的信息,请参阅5.2.2 节,而字符串的信息,请参阅5.2.3 节。

命令行后面的脚本参数被扩展为字面值,可将它用于所有接受字面值的上下文中,但引用不存在的参数编号将引致错误。

5.7.1 $1 ... $<NN> 将参数转换成整数

使用$1 ... $<NN> 将命令行参数转换成整数字面值。

5.7.2 @1 ... @<NN> 将参数转换成字符串

使用@1 ... @<NN> 将命令行参数转换成字符串字面值。

5.7.3 例子

以下述为例,假定该脚本的名字为example.stp

probe begin { printf("%d, %s/n", $1, @2) }

运行如下:

# stap example.stp 10 mystring

那么,$1 会被替换成10 ,而@2 会被替换成"mystring" ,结果输出:

10, mystring

5.8 条件编译

5.8.1 条件

词法分析工作包含简单的条件预处理阶段,它的语法形式类似于三元运算符(5.6.7 节),如下:

%( CONDITION %? TRUE-TOKENS %)

%( CONDITION %? TRUE-TOKENS %: FALSE-TOKENS %)

CONDITION 是一个有限表达式(limited expression ),它的语法格式由它的第一个关键字决定,下述是它的一般语法格式:

%( <condition> %? <code> [ %: <code> ] %)

5.8.2 基于内核版本号的条件: kernel_vkernel_vr

此种条件表达式的第一部分是标识符kernel_vkernel_vr ,第二部分是六个标准数值比较运算符``<'', ``<='', ``=='', ``!='', ``>'', or ``>='' 之一,第三部分字符串字面值,一个RPM 形式的版本- 发布号值。如果目标内核的版本(可使用-r 选项来重写该版本号)与给定的版本字符串匹配,那么该条件返回真,其中比较操作是由glibcstrverscmp 函数来实行的。

kernel_v 仅引用内核版本号数值,如"2.6.13"

kernel_vr 除于引用内核版本号数值外,还包含发布号后缀,如 “2.6.13-1.322FC3smp”

5.8.3 基于架构的条件:arch

这种条件表达式的第一部分是标识符arch ,它引用处理器架构类型,第二部分是字符串比较运算符”==””!=” ,第三部分字符串字面值。比较结果是简单的字符串相等和不相等。目前所支持的架构字符串分别有:i386i686x86_64ia64s390ppc64

5.8.4 TRUN-TOKENS FALSE-TOKENS

TRUE-TOKENS FALSE-TOKENS 是零个或多个语法单元(parser tokens ),可以包含嵌套的预处理条件。如果条件为真,则传递TRUE-TOKENS 到分析器的输入流,否则传递TRUE-TOKENS 。例如,下述例子中除非目标内核版本新于2.6.5 ,否则产生一个语法分析错误。

%( kernel_v <= "2.6.5" %? **ERROR** %) # invalid token sequence

下述代码可适合在不同的内核版本上运行。

probe kernel.function (

    %( kernel_v <= "2.6.12" %? "__mm_do_fault" %:

        %( kernel_vr == "2.6.13-1.8273FC3smp" %? "do_page_fault" %: UNSUPPORTED %)

     %)) { /* ... */ }

 

%( arch == "ia64" %?

    probe syscall.vliw = kernel.function("vliw_widget") {}

%)

下述代码适用于打开内核CONFIG_UTRACR( 译者注:原文是CONFIG ,估计是笔误)

%( CONFIG_UTRACE == "y" %?

    probe process.syscall {}

%)

 

你可能感兴趣的:(c,shell,脚本,System,语言,token)