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