summaryrefslogtreecommitdiff
path: root/tools/checker/file_format/c1visualizer/parser.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/checker/file_format/c1visualizer/parser.py')
-rw-r--r--tools/checker/file_format/c1visualizer/parser.py87
1 files changed, 87 insertions, 0 deletions
diff --git a/tools/checker/file_format/c1visualizer/parser.py b/tools/checker/file_format/c1visualizer/parser.py
new file mode 100644
index 0000000000..335a195883
--- /dev/null
+++ b/tools/checker/file_format/c1visualizer/parser.py
@@ -0,0 +1,87 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from common.logger import Logger
+from file_format.common import SplitStream
+from file_format.c1visualizer.struct import C1visualizerFile, C1visualizerPass
+
+import re
+
+class C1ParserState:
+ OutsideBlock, InsideCompilationBlock, StartingCfgBlock, InsideCfgBlock = range(4)
+
+ def __init__(self):
+ self.currentState = C1ParserState.OutsideBlock
+ self.lastMethodName = None
+
+def __parseC1Line(line, lineNo, state, fileName):
+ """ This function is invoked on each line of the output file and returns
+ a pair which instructs the parser how the line should be handled. If the
+ line is to be included in the current group, it is returned in the first
+ value. If the line starts a new output group, the name of the group is
+ returned in the second value.
+ """
+ if state.currentState == C1ParserState.StartingCfgBlock:
+ # Previous line started a new 'cfg' block which means that this one must
+ # contain the name of the pass (this is enforced by C1visualizer).
+ if re.match("name\s+\"[^\"]+\"", line):
+ # Extract the pass name, prepend it with the name of the method and
+ # return as the beginning of a new group.
+ state.currentState = C1ParserState.InsideCfgBlock
+ return (None, state.lastMethodName + " " + line.split("\"")[1])
+ else:
+ Logger.fail("Expected output group name", fileName, lineNo)
+
+ elif state.currentState == C1ParserState.InsideCfgBlock:
+ if line == "end_cfg":
+ state.currentState = C1ParserState.OutsideBlock
+ return (None, None)
+ else:
+ return (line, None)
+
+ elif state.currentState == C1ParserState.InsideCompilationBlock:
+ # Search for the method's name. Format: method "<name>"
+ if re.match("method\s+\"[^\"]*\"", line):
+ methodName = line.split("\"")[1].strip()
+ if not methodName:
+ Logger.fail("Empty method name in output", fileName, lineNo)
+ state.lastMethodName = methodName
+ elif line == "end_compilation":
+ state.currentState = C1ParserState.OutsideBlock
+ return (None, None)
+
+ else:
+ assert state.currentState == C1ParserState.OutsideBlock
+ if line == "begin_cfg":
+ # The line starts a new group but we'll wait until the next line from
+ # which we can extract the name of the pass.
+ if state.lastMethodName is None:
+ Logger.fail("Expected method header", fileName, lineNo)
+ state.currentState = C1ParserState.StartingCfgBlock
+ return (None, None)
+ elif line == "begin_compilation":
+ state.currentState = C1ParserState.InsideCompilationBlock
+ return (None, None)
+ else:
+ Logger.fail("C1visualizer line not inside a group", fileName, lineNo)
+
+def ParseC1visualizerStream(fileName, stream):
+ c1File = C1visualizerFile(fileName)
+ state = C1ParserState()
+ fnProcessLine = lambda line, lineNo: __parseC1Line(line, lineNo, state, fileName)
+ fnLineOutsideChunk = lambda line, lineNo: \
+ Logger.fail("C1visualizer line not inside a group", fileName, lineNo)
+ for passName, passLines, startLineNo in SplitStream(stream, fnProcessLine, fnLineOutsideChunk):
+ C1visualizerPass(c1File, passName, passLines, startLineNo + 1)
+ return c1File