@@ -144,7 +144,8 @@ public struct Parser {
|
||||
|
||||
public struct TransitionStatement {
|
||||
static func Compile(
|
||||
node: Node, forState state_identifier: Common.Identifier, withStatements stmts: [EvaluatableStatement], withTypesInScope scopes: LexicalScopes
|
||||
node: Node, forState state_identifier: Common.Identifier,
|
||||
withStatements stmts: [EvaluatableStatement], withTypesInScope scopes: LexicalScopes
|
||||
) -> Result<(ParserState, LexicalScopes)> {
|
||||
|
||||
#RequireNodeType<Node, (EvaluatableStatement, LexicalScopes)>(
|
||||
@@ -171,7 +172,10 @@ public struct Parser {
|
||||
node: next_node, withTypesInScopes: scopes)
|
||||
if case .Ok(let next_state) = maybe_parsed_next_state {
|
||||
return .Ok(
|
||||
(ParserStateDirectTransition(name: state_identifier, withStatements: stmts, withNextState: next_state), scopes))
|
||||
(
|
||||
ParserStateDirectTransition(
|
||||
name: state_identifier, withStatements: stmts, withNextState: next_state), scopes
|
||||
))
|
||||
} else {
|
||||
return .Error(
|
||||
Error(
|
||||
@@ -187,7 +191,11 @@ public struct Parser {
|
||||
{
|
||||
case .Ok(let tse):
|
||||
.Ok(
|
||||
(ParserStateSelectTransition(name: state_identifier, withStatements: stmts, withTransitioniExpression: tse as! SelectExpression), scopes))
|
||||
(
|
||||
ParserStateSelectTransition(
|
||||
name: state_identifier, withStatements: stmts,
|
||||
withTransitioniExpression: tse as! SelectExpression), scopes
|
||||
))
|
||||
case .Error(let e): .Error(e)
|
||||
}
|
||||
}
|
||||
@@ -249,12 +257,12 @@ public struct Parser {
|
||||
currentChild = node.child(at: currentChildIdx)
|
||||
if currentChild!.nodeType == "annotations" {
|
||||
return Result.Error(
|
||||
ErrorOnNode(node: currentChild!, withError: "Annotations in parser state are not yet handled."))
|
||||
ErrorOnNode(
|
||||
node: currentChild!, withError: "Annotations in parser state are not yet handled."))
|
||||
|
||||
// Would increment here.
|
||||
}
|
||||
|
||||
|
||||
// Skip the keyword state
|
||||
currentChildIdx += 1
|
||||
currentChildIdxSafe += 1
|
||||
@@ -306,7 +314,8 @@ public struct Parser {
|
||||
}
|
||||
currentChild = node.child(at: currentChildIdx)
|
||||
return TransitionStatement.Compile(
|
||||
node: currentChild!, forState: state_identifier, withStatements: parsed_s, withTypesInScope: current_scopes)
|
||||
node: currentChild!, forState: state_identifier, withStatements: parsed_s,
|
||||
withTypesInScope: current_scopes)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,7 +330,7 @@ public struct Parser {
|
||||
var error: Error? = .none
|
||||
|
||||
// TODO: Assert that there is only one.
|
||||
node.enumerateNamedChildren() { parser_state in
|
||||
node.enumerateNamedChildren { parser_state in
|
||||
if parser_state.nodeType != "parserState" {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public struct Program {
|
||||
|
||||
var errors: [Error] = Array()
|
||||
|
||||
result?.rootNode?.enumerateNamedChildren() { declaration_node in
|
||||
result?.rootNode?.enumerateNamedChildren { declaration_node in
|
||||
if declaration_node.nodeType != "declaration" {
|
||||
return
|
||||
}
|
||||
@@ -60,12 +60,14 @@ public struct Program {
|
||||
var currentChild: Node? = .none
|
||||
|
||||
if parser_node.childCount < currentChildIdxSafe {
|
||||
errors.append(ErrorOnNode(node: parser_node, withError: "Missing elements of parser declaration"))
|
||||
errors.append(
|
||||
ErrorOnNode(node: parser_node, withError: "Missing elements of parser declaration"))
|
||||
return
|
||||
}
|
||||
currentChild = parser_node.child(at: currentChildIdx)
|
||||
if currentChild!.nodeType != "parserType" {
|
||||
errors.append(ErrorOnNode(node: currentChild!, withError: "Missing type for parser declaration"))
|
||||
errors.append(
|
||||
ErrorOnNode(node: currentChild!, withError: "Missing type for parser declaration"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -79,14 +81,17 @@ public struct Program {
|
||||
|
||||
if type_node!.childCount < currentChildIdxSafe {
|
||||
errors.append(
|
||||
ErrorOnNode(node: parser_node, withError: "Missing elements of parser type in parser declaration"))
|
||||
ErrorOnNode(
|
||||
node: parser_node, withError: "Missing elements of parser type in parser declaration")
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
var currentChild = type_node!.child(at: currentChildIdx)
|
||||
if currentChild!.nodeType == "annotations" {
|
||||
errors.append(
|
||||
ErrorOnNode(node: currentChild!, withError: "Annotations in parser type are not yet handled."))
|
||||
ErrorOnNode(
|
||||
node: currentChild!, withError: "Annotations in parser type are not yet handled."))
|
||||
return
|
||||
|
||||
// Will increment indexes here.
|
||||
@@ -96,7 +101,8 @@ public struct Program {
|
||||
currentChildIdx += 1
|
||||
currentChildIdxSafe += 1
|
||||
if type_node!.childCount < currentChildIdxSafe {
|
||||
errors.append(ErrorOnNode(node: type_node!, withError: "Missing name in parser type declaration"))
|
||||
errors.append(
|
||||
ErrorOnNode(node: type_node!, withError: "Missing name in parser type declaration"))
|
||||
return
|
||||
}
|
||||
currentChild = type_node?.child(at: currentChildIdx)
|
||||
@@ -114,23 +120,26 @@ public struct Program {
|
||||
return
|
||||
}
|
||||
|
||||
currentChildIdx += 1;
|
||||
currentChildIdxSafe += 1;
|
||||
currentChildIdx += 1
|
||||
currentChildIdxSafe += 1
|
||||
if parser_node.childCount < currentChildIdxSafe {
|
||||
errors.append(ErrorOnNode(node: parser_node, withError: "Constructor parameters are not yet handled."))
|
||||
errors.append(
|
||||
ErrorOnNode(node: parser_node, withError: "Constructor parameters are not yet handled."))
|
||||
return
|
||||
}
|
||||
|
||||
if currentChild!.nodeType == "constructorParameters" {
|
||||
errors.append(ErrorOnNode(node: currentChild!, withError: "Constructor parameters are not yet handled."))
|
||||
errors.append(
|
||||
ErrorOnNode(node: currentChild!, withError: "Constructor parameters are not yet handled.")
|
||||
)
|
||||
return
|
||||
|
||||
// Will increment indexes here.
|
||||
}
|
||||
|
||||
// Skip the '{'
|
||||
currentChildIdx += 1;
|
||||
currentChildIdxSafe += 1;
|
||||
currentChildIdx += 1
|
||||
currentChildIdxSafe += 1
|
||||
if parser_node.childCount < currentChildIdxSafe {
|
||||
errors.append(Error(withMessage: "Missing body of parser declaration"))
|
||||
return
|
||||
@@ -138,7 +147,8 @@ public struct Program {
|
||||
currentChild = parser_node.child(at: currentChildIdx)
|
||||
|
||||
if currentChild!.nodeType == "parserLocalElements" {
|
||||
errors.append(ErrorOnNode(node: currentChild!, withError: "Parser Local Elements are not yet handled."))
|
||||
errors.append(
|
||||
ErrorOnNode(node: currentChild!, withError: "Parser Local Elements are not yet handled."))
|
||||
return
|
||||
// Will increment indexes here.
|
||||
}
|
||||
@@ -165,9 +175,11 @@ public struct Program {
|
||||
}
|
||||
|
||||
if !errors.isEmpty {
|
||||
return Result.Error(Error(withMessage: errors.map() { error in
|
||||
return error.msg
|
||||
}.joined(separator: ";")))
|
||||
return Result.Error(
|
||||
Error(
|
||||
withMessage: errors.map { error in
|
||||
return error.msg
|
||||
}.joined(separator: ";")))
|
||||
}
|
||||
|
||||
// Any of the types that are in the top-level scope should go into the program!
|
||||
|
||||
@@ -56,4 +56,3 @@ public struct SelectExpression {
|
||||
withSelector: self.selector, withKeysetExpressions: new_kse)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+32
-25
@@ -38,28 +38,28 @@ public struct ParserAssignmentStatement {
|
||||
/// A P4 Parser State
|
||||
///
|
||||
/// Note: A P4 Parser State is both a type and a value.
|
||||
public class ParserState: P4Type, P4Value, Equatable, CustomStringConvertible{
|
||||
public static func == (lhs: ParserState, rhs: ParserState) -> Bool {
|
||||
return lhs.state == rhs.state
|
||||
}
|
||||
public class ParserState: P4Type, P4Value, Equatable, CustomStringConvertible {
|
||||
public static func == (lhs: ParserState, rhs: ParserState) -> Bool {
|
||||
return lhs.state == rhs.state
|
||||
}
|
||||
|
||||
public func eq(rhs: any Common.P4Type) -> Bool {
|
||||
return switch rhs {
|
||||
case is ParserState: true
|
||||
default: false
|
||||
}
|
||||
public func eq(rhs: any Common.P4Type) -> Bool {
|
||||
return switch rhs {
|
||||
case is ParserState: true
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public func type() -> any Common.P4Type {
|
||||
return self
|
||||
}
|
||||
public func type() -> any Common.P4Type {
|
||||
return self
|
||||
}
|
||||
|
||||
public func eq(rhs: any Common.P4Value) -> Bool {
|
||||
return switch rhs {
|
||||
case let other as ParserState: self.state == other.state
|
||||
default: false
|
||||
}
|
||||
public func eq(rhs: any Common.P4Value) -> Bool {
|
||||
return switch rhs {
|
||||
case let other as ParserState: self.state == other.state
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public private(set) var state: Identifier
|
||||
public private(set) var statements: [EvaluatableStatement]
|
||||
@@ -85,12 +85,14 @@ public class ParserState: P4Type, P4Value, Equatable, CustomStringConvertible{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class ParserStateDirectTransition: ParserState {
|
||||
|
||||
private let next_state: Identifier
|
||||
|
||||
public init(name: Identifier, withStatements stmts: [EvaluatableStatement], withNextState next_state: Identifier) {
|
||||
public init(
|
||||
name: Identifier, withStatements stmts: [EvaluatableStatement],
|
||||
withNextState next_state: Identifier
|
||||
) {
|
||||
self.next_state = next_state
|
||||
super.init(name: name, withStatements: stmts)
|
||||
}
|
||||
@@ -121,14 +123,19 @@ public class ParserStateSelectTransition: ParserState {
|
||||
return "State (Name: \(super.state) (select transition))"
|
||||
}
|
||||
|
||||
public init(name: Identifier, withStatements stmts: [any EvaluatableStatement], withTransitioniExpression te: SelectExpression) {
|
||||
public init(
|
||||
name: Identifier, withStatements stmts: [any EvaluatableStatement],
|
||||
withTransitioniExpression te: SelectExpression
|
||||
) {
|
||||
self.selectExpression = te
|
||||
super.init(name: name, withStatements: stmts)
|
||||
}
|
||||
}
|
||||
|
||||
nonisolated(unsafe) public let accept = ParserStateNoTransition(name: Identifier(name: "accept"), withStatements: [])
|
||||
nonisolated(unsafe) public let reject = ParserStateNoTransition(name: Identifier(name: "reject"), withStatements: [])
|
||||
nonisolated(unsafe) public let accept = ParserStateNoTransition(
|
||||
name: Identifier(name: "accept"), withStatements: [])
|
||||
nonisolated(unsafe) public let reject = ParserStateNoTransition(
|
||||
name: Identifier(name: "reject"), withStatements: [])
|
||||
|
||||
public struct ParserStates {
|
||||
public var states: [ParserState] = Array()
|
||||
@@ -165,9 +172,9 @@ public struct ParserStates {
|
||||
///
|
||||
/// Note: A Parser is both a type _and_ a value.
|
||||
public struct Parser: P4Type, P4Value {
|
||||
public func type() -> any Common.P4Type {
|
||||
return self
|
||||
}
|
||||
public func type() -> any Common.P4Type {
|
||||
return self
|
||||
}
|
||||
|
||||
public func eq(rhs: any Common.P4Type) -> Bool {
|
||||
return switch rhs {
|
||||
|
||||
@@ -126,11 +126,13 @@ extension Parser: ParserExecution {
|
||||
}
|
||||
|
||||
guard let _current_state = self.findStartState(),
|
||||
var current_state = _current_state as? EvaluatableParserState else {
|
||||
return (reject, execution.setError(error: Error(withMessage: "Could not find the start state")))
|
||||
var current_state = _current_state as? EvaluatableParserState
|
||||
else {
|
||||
return (
|
||||
reject, execution.setError(error: Error(withMessage: "Could not find the start state"))
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// Evaluate until the state is either accept or reject.
|
||||
while !current_state.done() && !execution.hasError() {
|
||||
(current_state, execution) = current_state.execute(program: execution)
|
||||
|
||||
Reference in New Issue
Block a user