Common markup languages and common programming languages are indistinguishable in that they have both syntax and semantics. They differ only in that the purpose of a programming language is to generate executable code for a processor, while the purpose of a markup language is to generate declarative data for a display engine.
Both have a lexical structure. They are made up of tokens like words and numbers and punctuation.
Both have a syntactical structure. The tokens can be arranged in many different ways, and some arrangements are valid while others are not.
Both have a semantic structure. The tokens have meaning, some being predefined and some user-defined, and the way that tokens are arranged has meaning.
If we take the following code fragment:
<div class="yolo">Hello world</div>
The tokens div, class and the angle brackets have pre-defined meanings. The token "yolo" is a string which provides a user-defined name for the div. The angle brackets separate the markup from the text. These are semantic observations.
For both, the parser phase of the compiler stops at the same point, when it has generated a suitable internal representation (such as an AST).
The next phase for a programming language is to generate code. The next phase for a markup language could be to generate a DOM. That phase is dependent on the the semantics, but not part of it.