我正在构建一个带有flex的词法分析器。我必须对具有四个以上指令的函数执行某些操作。如何计算C源文件中的指令数?我试着计算分号的数量(;),但我如何处理这样的情况:if(strcmp(str1,str2)== 2&& strlen(str1)> 4) 我上面有多少指令?我认为有六条指令:if,strcmp,strlen,&&,==,> 。有没有定义指令的模式?
答案 0 :(得分:1)
我认为你不能在词汇上做到这一点,你至少需要进行一些句法分析,也可能需要进行语义分析。
此外,您需要定义"指令"是第一个,在你开始考虑计算它们之前。毕竟,术语"指令"在C中没有任何意义,你首先需要给它一个。
答案 1 :(得分:0)
脱离我的头顶:
您需要在括号前面观察代表未解析值的标记(它们不是任何基本运算符)。这些可以被假定为指令。
您同样希望将比较运算符作为一种指令形式放在词法分析器中。
一个角落的情况是,如果它是一个标记以“它可能被认为是一个字符串的开头,并以”没有前面的\标记字符串结尾的结尾“开头。这些应该组合成一个字符串标记。
使用C中关于如何命名变量和函数的规则来帮助您将未解析的值分解为标记序列。 (示例:令牌8 * 4 *(打破C中命名的规则,因此您知道应该使用运算符作为分隔符将其拆分来解析未解析的值)
答案 2 :(得分:0)
我无法抗拒这个问题,因为我目前正在考虑将Haskell用作分析和批量编辑我的C项目的一种荣耀perl
,并想知道使用{{3}是多么简单} 为了这。当然还有很多其他的Language-C(正如Jörg指出的那样, lexical 分析器不会在这里切割芥末!),在更流行的语言中,但无论如何,这里有:
module Main where
import System.Environment
import Language.C.Parser
import Language.C.Data.InputStream
import Language.C.Data.Position
import Language.C.Syntax.AST
import Language.C.Syntax.Utils
import Language.C.Analysis.DeclAnalysis
import Language.C.Data.Ident
main :: IO ()
main = do
[cFileName] <- getArgs
stream <- readInputStream cFileName
let startpos = initPos cFileName
case parseC stream startpos of
Left parseError -> error $ show parseError
Right translation -> mapM_ (putStrLn . show) $ mungeTrans translation
mungeTrans (CTranslUnit decls _) = mungeDecls decls
mungeDecls [] = []
mungeDecls ((CFDefExt funDef):decls) = mungeFunDef funDef : mungeDecls decls
mungeDecls (_:decls) = mungeDecls decls
mungeFunDef (CFunDef _ declarator _ cStatement _) = (nameOf declarator, numberOfStatements cStatement) where
nameOf (CDeclr (Just name) _ _ _ _) = identToString name
nameOf _ = "?"
numberOfStatements cstat = case getSubStmts cstat of
[] -> 1
block -> foldl1 (+) $ map numberOfStatements block
我希望非haskellers可以跟踪正在发生的事情:mungeDecls
遍历语法树,并且只考虑函数声明,它们被分析(通过mungeFunDef
)到函数名和数字中的陈述。
使用getSubStmts
效用函数(good analysers)懦弱地回避了问题“C语句究竟是什么”。将f(x) && g(x);
视为一个陈述,而不是两个陈述。
("main",12)
("fork_child",21)
("main_loop",306)
("init_rlwrap",61)
("check_optarg",2)
("current_option",4)
etc.
我希望Haskell这个无耻的插件说服一些人尝试这种工作!!